2

基于vite3+tauri模拟QQ登录切换窗体|Tauri自定义拖拽|最小/大/关闭 - xiaoyan2017

 1 year ago
source link: https://www.cnblogs.com/xiaoyan2017/p/16818283.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

前两天有给大家分享tauri+vue3快速搭建项目、封装桌面端多开窗口。今天继续来分享tauri创建启动窗口、登录窗口切换到主窗口及自定义拖拽区域的一些知识。希望对想要学习或正在学习的小伙伴有些帮助。

1289798-20221023104501223-1068247515.png

  

1289798-20221023104533278-1081937733.png
  • tauri+vue3登录窗口切换主窗口

<!-- 登录模板 -->
<template>
    <div>
        <div class="ntMain__cont flex1 flexbox flex-col">
            <div class="nt__lgregWrapper flex1 flexbox flex-col">
                <NavBar transparent />

                <div class="nt__lgregBox flex1">
                    <div class="banner">
                        <h2 class="tit flexbox flex-alignc"><img src="@assets/logo.png" />TAURI-VUE3-CAHT</h2>
                        <img class="bg" src="/static/skin/bg-banner.jpg" />
                    </div>
                    <div class="forms">
                        <form @submit.prevent="handleSubmit">
                            <ul class="clearfix">
                                <li><input class="iptxt flex1" type="text" v-model="formObj.tel" placeholder="请输入手机号" /></li>
                                <li><input class="iptxt flex1" type="password" v-model="formObj.pwd" placeholder="请输入密码"/></li>
                            </ul>
                            <div class="btns">
                                <el-button type="primary" native-type="submit" size="default" auto-insert-space>登录</el-button>
                            </div>
                            <div class="lgregLink align-c clearfix">
                                <router-link class="navigator" to="#">忘记密码</router-link>
                                <router-link class="navigator" to="/register">注册账号</router-link>
                            </div>
                            <!-- ... -->
                        </form>
                    </div>
                </div>
                <!-- ... -->
            </div>
        </div>
    </div>
</template>

<script setup>
    import { ref, reactive, inject } from 'vue'
    import { useStore } from 'vuex'

    import { mainWin } from '@/windows/actions'

    const store = useStore()

    const v3layer = inject('v3layer')

    const utils = inject('utils')

    const formObj = reactive({})

    const VMsg = (content) => {
        v3layer.message({ content, icon: 'error', shade: true })
    }

    const handleSubmit = () => {
        if(!formObj.tel){
            VMsg('手机号不能为空')
        }else if(!utils.checkTel(formObj.tel)){
            VMsg('手机号格式不正确')
        }else if(!formObj.pwd){
            VMsg('密码不能为空')
        }else{
            // 一些逻辑处理...
            
            v3layer({
                type: 'toast',
                icon: 'success',
                content: '登录成功',
                time: 2,
                onEnd() {
                    // 跳转主窗口(会关闭登录窗口)
                    mainWin()
                }
            })
        }
    }
</script>

windows/actions.js 定义登录及主窗口函数。

1289798-20221023110018766-1281778498.png

注意:当只需要一个主窗口,则需要在 label 标识中加入 main字符。

因为在创建窗口的时候,会 检测main字符 是否存在,存在则只允许有一个主窗口。

// 创建新窗口
async createWin(options) {
    const args = Object.assign({}, windowConfig, options)
    
    // 是否主窗口
    if(args.label.indexOf('main') > -1) {
        console.log('该窗口是主窗口')
        this.mainWin = getAll().find(w => w.label.indexOf('main') > -1 && w.label != args.label)
        await this.mainWin?.hide()
    }

    // 创建窗口对象
    let win = new WebviewWindow(args.label, args)
    // 是否最大化
    if(args.maximized && args.resizable) {
        win.maximize()
    }

    // 窗口创建完毕/失败
    win.once('tauri://created', async() => {
        console.log('window create success!')
        await win?.show()
        await this.mainWin?.close()
    })

    win.once('tauri://error', async() => {
        console.log('window create error!')
    })
}

另外创建新窗口的时候,总会有一下左上角到居中闪动窗口。在配置参数中设置 visible: false 隐藏窗口,当窗口创建完毕,再show显示窗口即可解决。

// 系统参数配置
export const windowConfig = {
    label: null,            // 窗口唯一label
    title: '',              // 窗口标题
    url: '',                // 路由地址url
    width: 900,             // 窗口宽度
    height: 640,            // 窗口高度
    minWidth: null,         // 窗口最小宽度
    minHeight: null,        // 窗口最小高度
    x: null,                // 窗口相对于屏幕左侧坐标
    y: null,                // 窗口相对于屏幕顶端坐标
    center: true,           // 窗口居中显示
    resizable: true,        // 是否支持缩放
    maximized: false,       // 最大化窗口
    decorations: false,     // 窗口是否无边框及导航条
    alwaysOnTop: false,     // 置顶窗口
    fileDropEnabled: false, // 禁止系统拖放
    visible: false,         // 隐藏窗口
}
1289798-20221023111324313-909589056.gif

如果想制作启动窗口,可以去官方文档查阅资料。

1289798-20221023115409603-925002194.png

https://tauri.app/zh/v1/guides/features/splashscreen

  • tauri+vue3实现无边框自定义拖拽区域

配置参数设置 decorations: false 属性,则创建的窗口没有边框及导航栏。这时候就需要自定义拖拽及最小化/最大化及关闭按钮了。

1289798-20221023111816275-1534702679.gif

tauri 提供了 data-tauri-drag-region 属性,用来自定义元素拖动功能。

<template>
    <div class="nt__navbar" :class="{'fixed': fixed || transparent}">
        <div data-tauri-drag-region class="nt__navbar-wrap flexbox flex-alignc">
            <div class="nt__navbar-title" :class="{'center': center}">
                <template v-if="$slots.title"><slot name="title" /></template>
                <template v-else>{{title}}</template>
            </div>
        </div>
        <WinTool :minimizable="minimizable" :maximizable="maximizable" :closable="closable">
            <slot name="wbtn" />
        </WinTool>
    </div>
</template>

1289798-20221023112533119-390664452.png

1289798-20221023112652309-368039219.png

1289798-20221023112743290-1040480495.png

新建一个 winTool.vue 组件,自定义右上角按钮操作。

<!-- 右上角操作按钮 -->
<template>
    <div class="taui__winbtn">
        <div class="taui__winbtn-groups">
            <slot />
            <a v-if="minimizable" class="wbtn" title="最小化" @click="handleWinMin"><i class="iconfont icon-min"></i></a>
            <a v-if="maximizable && isResizable" class="wbtn" :title="isMaximized ? '向下还原' : '最大化'" @click="handleWinMax2Min">
                <i class="iconfont" :class="isMaximized ? 'icon-restore' : 'icon-max'"></i>
            </a>
            <a v-if="closable" class="wbtn close" title="关闭" @click="handleWinClose"><i class="iconfont icon-quit"></i></a>
        </div>
    </div>
</template>

<script setup>
import { onMounted, reactive, inject, toRefs } from 'vue'
import { useStore } from 'vuex'
import { appWindow } from '@tauri-apps/api/window'
import { listen } from '@tauri-apps/api/event'
import { exit } from '@tauri-apps/api/process'

// ...
const store = useStore() const v3layer = inject('v3layer') const data = reactive({ isMaximized: false, isResizable: true }) onMounted(async() => { data.isMaximized = await appWindow.isMaximized() data.isResizable = await appWindow.isResizable() listen('tauri://resize', async() => { data.isMaximized = await appWindow.isMaximized() }) }) // 最小化 const handleWinMin = async() => { await appWindow.minimize() } // 最大化/还原 const handleWinMax2Min = async() => { const resizable = await appWindow.isResizable() if(!resizable) return await appWindow.toggleMaximize() } // 关闭 const handleWinClose = async() => { if(appWindow.label.indexOf('main') > -1) { let $el = v3layer({ type: 'android', content: '确认退出应用程序吗?', btns: [ { text: '最小化托盘', style: 'color:#24c8db', click: () => { await appWindow.hide() } }, { text: '退出程序', style: 'color:#ff5438', click: async() => { store.commit('LOGOUT') await exit() } } ] }) }else { await appWindow.close() } } </script>

如下图:导航条支持自定义背景/透明背景,自定义插槽按钮等功能。

1289798-20221023114141842-1532951234.png
<NavBar transparent>
    <template #title><i class="iconfont icon-pyq2"></i> 朋友圈</template>
    <template #wbtn>
        <a class="wbtn" title="更换封面"><i class="iconfont icon-dianzan"></i></a>
        <a class="wbtn" title="发布" @click="isShowPublish=true"><i class="iconfont icon-choose"></i></a>
    </template>
</NavBar>

Okr,以上就是tauri创建登录窗口切换、自定义拖拽窗口的一些小分享。

https://www.cnblogs.com/xiaoyan2017/p/16812092.html

1289798-20221023114946796-1587239939.gif


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK