vue3.x简单实现wx.showModal()

2020-11-30T13:14:59.png

引言

开发过微信小程序的同学想必都对wx.showModal不陌生。用起来还是比较方便的,以api的形式挂载在全局对象wx上,只需调用一下这个api即可显示一个弹窗,还可以根据设置的参数做一些定制。一些知名的组件库,也实现了此类功能。比如element的$message。所以,我也来分享一个简单实现方式,以此来加深对Vue的理解。

代码结构

2020-11-30T15:17:32.png

在Message目录下,有着两个文件,vue文件负责组件内容,js负责处理服务APi。

实现原理

首先使用vue文件创建一个弹窗组件,然后按正常写组件方式写一个组件逻辑。唯一不同的是引入方式不一样,不在别的组件中引用该组件。使用js文件将其注册到全局api,调用该api。

实现过程

注意:本文使用的是Vue3.x版本。由于本人Vue3.x也正出于学习之处,如有理解/实现不当之处,恳请指正!

Vue文件


<template>

    <div v-if="visible" class="tm-message-wrapper">

        <div class="tm-message-dialog">

            <div class="tm-message-title">{{ title }}</div>

            <div class="tm-message-content">{{ content }}</div>

            <div class="tm-message-noRepeat" v-if="showNoRepeat"><input type="checkbox" v-model="noRepeat">不再提示</div>

            <div class="tm-message-operation-area">

                <div class="tm-message-cancel tm-message-operation" @click="action('cancel')">取消</div>

                <div class="tm-message-confirm tm-message-operation" @click="action('confirm')">确定</div>

            </div>

        </div>

    </div>

</template>



<script>

export default {

    data() {

        return {

            uid: "default",

            visible: false,

            title: "提示",

            content: "消息内容",

            showNoRepeat: false,

            noRepeat: false,

            callBack: null

        }

    },

    methods: {

        action(action) {

            this.visible = false

            if (action == "confirm" && this.showNoRepeat && this.noRepeat) {

                window.localStorage.setItem(this.uid, true)

            }

            if (this.callBack instanceof Function) {

                this.callBack(action)

            }

        }

    }

}

</script>

该文件没有什么特别值得注意的地方,唯一一个跟普通组件写法不一样的就是多了一个callBack回调。

js文件


import { createApp } from 'vue'

import Message from "./index.vue"





const msg = options => {

    const NoticeInstance = createApp(Message)

    let msgNode = document.createElement('div');

    NoticeInstance.vm = NoticeInstance.mount(msgNode);

    if (options && Object.keys(options).length > 0) {

        Object.assign(NoticeInstance.vm, options)

    }

    console.log(NoticeInstance)

    NoticeInstance.vm.visible = true;

    NoticeInstance.dom = NoticeInstance.vm.$el;

    document.body.appendChild(NoticeInstance.dom)

    return NoticeInstance.vm

}

export default msg;

js文件首先创建了一个app实例,然后将其挂载到一个新的html元素,随后进行一些属性的赋值操作。最后将实例追加之文档的body末尾。

引入

main.js


import { createApp } from 'vue'

import App from './App.vue'



import Message from "../tm-ui/components/Message"



const app = createApp(App)

app.config.globalProperties.$message = Message;



app.mount('#app')

调用

test.vue


<template>

  <div @click="showModal" class="bg-blue text-lg">

      点我弹窗(wx.showModal)

  </div>

</template>



<script>

export default {

    methods:{

        showModal(){

            this.$message({

                title:"弹窗标题",

                content:"弹窗内容",

                callBack: (action) => {

                    if(action == 'confirm') {

                        console.log("点击了确定")

                    }

                }

            })

        }

    }

}

</script>



<style>



</style>

2020-11-30T15:18:35.png

后记

相比于Vue2.x,vue3.x的设计理念更偏向于函数式编程,比如不在默认导出Vue对象,而是使用createApp的方式创建一个实例。而这个showModal的实现虽然达到了效果,但用起来依旧缺少了函数式编程的美感。相比于微信小程序showModal的对象函数回调写法。我个人更偏向于element的messag实现。返回一个Promise对象,确认操作在then()调用里面,取消操作在catch()异常处理。感觉这样会更具有与Vue3统一的编程式美感。

版权声明: 本文首发于 指尖魔法屋-vue3.x简单实现wx.showModal()(https://blog.thinkmoon.cn/post/936_vue3_x%E7%AE%80%E5%8D%95%E5%AE%9E%E7%8E%B0wx_showmodal__/) 转载或引用必须申明原指尖魔法屋来源及源地址!