uni-app开发全局弹层组件

幽映每白日,清辉照衣裳。这篇文章主要讲述uni-app开发全局弹层组件相关的知识,希望能为你提供帮助。
根据弹层经常使用的方法和方式可以大致列出他需要的属性和方法:
前几项就很好做,就在data中定义好字段,外层直接拿官方的轮子uni-popup,这样少写一些控制弹出的逻辑(懒的),这样大致结构就写好了

// template部分 < uni-popup ref="popup" :maskClick="maskClick"> < view class="st-layer" :style=" width: width "> < view class="st-layer__content"> < !-- #ifndef APP-NVUE --> < text class="st-layer__icon" :class="option.iconClass || getIconClass()" v-if="option.type !== none & & option.showIcon"> < /text> < !-- #endif --> < view class="st-layer__msg" v-if="option.msg"> < text> option.msg < /text> < /view> < /view> < view class="st-layer__footer" :class="is-reverse-cofirmcancel : isReverseConfirmCancel" v-if="option.showConfirmButton || option.showCancelButton"> < view class="st-layer__footer__btn st-layer__footer__btn--confirm" @tap.stop="confirmClick" v-if="option.showConfirmButton"> < text> 确认< /text> < /view> < view class="st-layer__footer__btn st-layer__footer__btn--cancel" @tap.stop="cancelClick" v-if="option.showCancelButton"> < text> 取消< /text> < /view> < /view> < /view> < /uni-popup>

然后js部分先简单实现了一些open和close方法
data() return option: , methods: open(option) let defaultOption = showCancelButton: false, // 是否显示取消按钮 cancelButtonText: 取消, // 取消按钮文字 showConfirmButton: true, // 是否显示确认按钮 confirmButtonText: 取消, // 确认按钮文字 showIcon: true, // 是否显示图标 iconClass: null, // 图标class自定义 type: none, // 类型 confirm: null, // 点击确认后的逻辑 cancel: null, // 点击取消后的逻辑 msg: this.option = Object.assign(, defaultOption, option) this.$refs.popup.open() , close() this.$refs.popup.close() , confirmClick() const confirmHandler = this.option.confirm if (confirmHandler & & typeof confirmHandler === function) confirmHandler()this.close() this.$emit(confirm) , cancelClick() const cancelHandler = this.option.cancel if (cancelHandler & & typeof cancelHandler === function) cancelHandler()this.close() this.$emit(cancel)

目前在其他页面已经可以使用
// test.vue可以使用uni-app的 [easycom组件规范](https://uniapp.dcloud.io/component/README?id=easycom%e7%bb%84%e4%bb%b6%e8%a7%84%e8%8c%83),不用写import语句 < st-layer ref="stLayer"> < /st-layer>

// js部分 this.$refs.stLayer.open( msg: 测试, confirm: () => console.log(点击了确认) , cancel: () => console.log(点击了取消))

现在基本功能已经实现,但是有人要说了,这样调用不方便,我想这样调用
open(msg).then(() => console.log(点击了确认) ).catch(() => console.log(点击了取消) )

那如何实现promise化呢?最简单的方法就是让open方法返回一个promise。如何点击确认或取消的时候进入then方法呢,看下面的写法
... open() return new promise((reoslve, reject) => ... this.option.confirm = this.option.confirm || function confirmResolve () resolve()this.option.cancel = this.option.cancel || function cancelReject () reject()) ...

如果要封装其他单独的方法,比如confirm之类,可以在open基础上扩展:
confirm(msg, option = ) if (typeof msg === object) option = msg else option.msg = msgreturn this.open( ...option, showCancelButton: true, type: confirm )// 调用方式 this.$refs.stLayer.confirm(是否确认?).then().catch()

这样基本的弹层组件已经实现。下面也就是最后一步全局使用原有vue项目写的layer组件要全局使用通常是采用下面的方法注入到页面中
import main from ./main.vueconst LayerConstructor = vue.extend(main)const initInstance = () => instance = new LayerConstructor( el: document.createElement(div) )instance.callback = defaultCallback document.getElementById(app).appendChild(instance.$el)

直接拉过来用,结果报错,提示error: document is undefined,才想起uni-app跟普通vue项目的有一个很大的区别,在它的运行原理中有介绍:
【uni-app开发全局弹层组件】所以这种注册全局的方法已经不可用。那该如何在uni-app中实现呢? 翻看官方论坛,找到了一个实现loadervue-inset-loader,实现原理就是获取sfc模板内容,在指定位置插入自定义内容(也就是需要全局的组件),使用方式如下:
// 第一步 npm install vue-inset-loader --save-dev // 第二步 在vue.config.js(hbuilderx创建的项目没有的话新建一个)中注入loader module.export = chainWebpack: config => // 超级全局组件 config.module .rule(vue) .test(/\\.vue$/) .use() .loader(path.resolve(__dirname, "./node_modules/vue-inset-loader")) .end()// 支持自定义pages.json文件路径 // options: //pagesPath: path.resolve(__dirname,./src/pages.json) // // 第三步 pages.json配置文件中添加insetLoader "insetLoader": "config": "confirm": "< BaseConfirm ref=confirm> < /BaseConfirm> ", "abc": "< BaseAbc ref=BaseAbc> < /BaseAbc> " , // 全局配置 "label":["confirm"], "rootEle":"div"

配置说明
到这,该组件就可以全局使用了,不需要在每个页面写标签使用,只需要调用api就可以。
后面可以再根据使用情况进行优化处理。水平有限,欢迎各位大佬指点。

    推荐阅读