tauri+vite3 crée une fenêtre de connexion|zone de glisser personnalisée tauri

Dans l'article précédent, j'ai expliqué avec vous comment créer plusieurs fenêtres avec Tauri. Cette fois, je partage la création par Tauri d'une fenêtre de connexion qui passe à la fenêtre principale et aux éléments personnalisés de glisser-déposer/réduire/agrandir et fermer.

tauri+vue3 crée une application multi-fenêtres

Insérer la description de l'image ici

tauri crée un formulaire de connexion

<!-- 登录模板 -->
<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>

Insérer la description de l'image ici

Comme indiqué ci-dessus : fonctions de connexion et de construction du formulaire principal.

Insérer la description de l'image ici

labelLorsqu'il contient maindes caractères, cela signifie qu'il ne peut y avoir qu'un seul formulaire principal. Lorsque la connexion est réussie, le formulaire de connexion est fermé et la fenêtre principale s'affiche.

// 创建新窗口
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!')
    })
}

Afin de résoudre le problème de la création d'une nouvelle fenêtre, il y aura toujours une fenêtre clignotante du coin supérieur gauche vers le centre. Définissez simplement visible: false dans les paramètres de configuration pour masquer la fenêtre et créer une fenêtre d'affichage réussie.

// 系统参数配置
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,         // 隐藏窗口
}

Tauri crée une forme de traînée sans frontières

Lors de la définition decorations: falsede la propriété, la fenêtre est créée sans bordures ni navigation. À ce stade, vous devez personnaliser les boutons glisser-déposer, minimiser/agrandir et fermer.

Insérer la description de l'image ici
Définissez l'attribut sur l'élément qui doit être déplacé data-tauri-drag-regionpour réaliser la fonction de déplacement d'élément personnalisé.

<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>

Insérer la description de l'image ici

<!-- 右上角操作按钮 -->
<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>

Insérer la description de l'image ici
Comme indiqué ci-dessus : la barre de navigation prend en charge l'arrière-plan personnalisé/l'arrière-plan transparent et les emplacements personnalisés (bouton icône dans le coin supérieur droit)

<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>

Ci-dessus, quelques partages sur la façon dont tauri+vite3 crée des fenêtres de connexion et personnalise les formulaires glisser-déposer.

Je suppose que tu aimes

Origine blog.csdn.net/yanxinyun1990/article/details/127506099
conseillé
Classement