• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • dedecms
  • ecshop
  • z-blog
  • UcHome
  • UCenter
  • drupal
  • WordPress
  • 帝国cms
  • phpcms
  • 动易cms
  • phpwind
  • discuz
  • 科汛cms
  • 风讯cms
  • 建站教程
  • 运营技巧
您的位置:首页 > CMS教程 >建站教程 > uni-app中怎么开发一个全局弹层组件(代码示例)

uni-app中怎么开发一个全局弹层组件(代码示例)

作者:站长图库 字体:[增加 减小] 来源:互联网 时间:2022-04-29

站长图库向大家介绍了uni-app,全局弹层组件,代码示例等相关知识,希望对您有所帮助

uni-app中怎么开发一个全局弹层组件?下面本篇文章给大家通过例子介绍一下uni-app中实现一个全局弹层组件的方法,希望对大家有所帮助!


uni-app中怎么开发一个全局弹层组件(代码示例)


公司有一个采用uni-app框架写的app应用,里面的弹层基本是使用官方的uni.showModal之类的api实现弹层,在设备上表现就是原生的弹层,在客户的要求下,需要更换成设计的样式,所以就开始实现这样一个组件。

根据弹层经常使用的方法和方式可以大致列出他需要的属性和方法:

类型:alert/confirm等

展示图标 icon

展示内容 content

可以api调用

支持promise,可以使用$api.xx().then

前几项就很好做,就在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 = msg        }        return this.open({                ...option,                showCancelButton: true,                type: 'confirm'        })}// 调用方式this.$refs.stLayer.confirm('是否确认?').then().catch()

这样基本的弹层组件已经实现。下面也就是最后一步全局使用原有vue项目写的layer组件要全局使用通常是采用下面的方法注入到页面中

import main from './main.vue' const 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 逻辑层和视图层分离,在非H5端运行时,从架构上分为逻辑层和视图层两个部分。逻辑层负责执行业务逻辑,也就是运行js代码,视图层负责页面渲染。虽然开发者在一个vue页面里写js和css,但其实,编译时就已经将它们拆分了。逻辑层是运行在一个独立的jscore里的,它不依赖于本机的webview,所以一方面它没有浏览器兼容问题,可以在Android4.4上跑es6代码,另一方面,它无法运行window、document、navigator、localstorage等浏览器专用的js API。

所以这种注册全局的方法已经不可用。那该如何在uni-app中实现呢? 翻看官方论坛,找到了一个实现loadervue-inset-loader,实现原理就是获取sfc模板内容,在指定位置插入自定义内容(也就是需要全局的组件),使用方式如下:

// 第一步npm install vue-inset-loader --save-dev // 第二步 在vue.config.js(hbuilderx创建的项目没有的话新建一个)中注入loadermodule.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" }

配置说明

config (default: {})

定义标签名称和内容的键值对

label(default: [])

需要全局引入的标签,打包后会在所有页面引入此标签

rootEle(default: "div")

根元素的标签类型,缺省值为div,支持正则,比如匹配任意标签 ".*"

label 和 rootEle 支持在单独页面的style里配置,优先级高于全局配置

到这,该组件就可以全局使用了,不需要在每个页面写标签使用,只需要调用api就可以。

后面可以再根据使用情况进行优化处理。水平有限,欢迎各位大佬指点。



分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 如何快速搭建uni-app项目?两种搭建方法分享
  • 移动uni-app项目怎么实现发送位置的地图交互
  • uni-app中怎么开发一个全局弹层组件(代码示例)
  • 遇到的uni-app的坑(uni-easyinput清空值,datetimerange置空)
  • uni-app介绍全局样式引入和底部导航栏开发
  • 解决uni-app入坑集合的一种方案
  • 聊聊怎么将小程序项目转为uni-app项目
  • 浅析uni-app中怎么提交form表单?(代码解析)
  • 一起分析uni-app怎么实现上传图片
  • 看看使用uni-app如何编写一个五子棋小游戏

相关文章

  • 2022-04-29屏蔽无用的WordPress默认小工具
  • 2022-04-29PHP中如何利用define定义常量
  • 2022-04-29基于thinkphp6.x的API接口开发简单小实例
  • 2022-04-29Mysql报错“Incorrect key file for table” 数据库表显示“使用中”解决办法
  • 2022-04-29Angular中怎么自定义视频播放器
  • 2022-04-2910个超级有用的PHP代码片段(建议收藏)
  • 2022-04-29Javascript中window.close如何不提示弹窗
  • 2022-04-29设置一个无需输入密码的WordPress登录表单
  • 2022-04-29WordPress图片显示模糊的问题
  • 2022-04-29html5新增的表单控件和表单属性有哪些

文章分类

  • dedecms
  • ecshop
  • z-blog
  • UcHome
  • UCenter
  • drupal
  • WordPress
  • 帝国cms
  • phpcms
  • 动易cms
  • phpwind
  • discuz
  • 科汛cms
  • 风讯cms
  • 建站教程
  • 运营技巧

最近更新的内容

    • PhotoShop制作逼真的墙面粉笔字效果
    • Laravel隐藏index.php的方法
    • Photoshop设计大气时尚的金色花纹教程
    • PHP怎么实现加好友功能
    • PhotoShop制作蓝色梦幻动漫签名溶图教程
    • vue.js怎么实现二级下拉悬浮菜单
    • 详解Angular中的NgModule(模块)
    • 教你5个让Vue3开发更顺畅的知识点
    • 解决并分析Incorrect datetime value报错问题
    • 如何修改织梦cms的幻灯片调用为全站调用

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有