• 技术文章 >web前端 >uni-app

    聊聊使用Uniapp怎么实现全局消息提示及其组件

    青灯夜游青灯夜游2022-06-22 22:00:54转载276
    Uniapp中怎么实现全局消息提示及其组件?下面本篇文章给大家介绍一下Uniapp全局消息提示及其组件的实现方法,希望对大家有所帮助!

    最近有项目需求我们能够在H5及小程序中全局实时刷新消息,并且在全局做一个消息提示,提示组件也需要自定义样式,首先实时消息的刷新无非有两种,一种是短轮询,一种是长轮询。
    所谓短轮询,其实就是前端使用定时器,在一定间隔时间内向后端发起请求,并且后端需要对轮询请求做优化。
    长轮询则是将消息请求发送到后端后,请求挂起,等待后端有新消息返回后,再重新发起消息请求,实则是一个websocket通信,鉴于项目上线时间以及成本,最后选择短轮询方式,且全局消息提示在App.vue中进行。

    实现

    1.短轮询请求-App.vue中

       async created(){const _this=thissetInterval(async ()=>{
                    const res=await _this.$ajax({                
                    url:`/api/notice/status`
                  })             
                  if(res.data.code===200){
                    const value=res.data.data.hasNew
    		_this.$store.commit({type: 'changeNew', value})
                  }
             },6000)	
        }

    2.全局消息提示组件

    消息请求后需要有一个全局的自定义组件来展示消息,但是遇到一个问题,那就是在Unipp中, 虽然App.vue是uni-app的主组件,所有页面都是在App.vue下进行切换的,是页面入口文件。但App.vue本身不是页面,这里不能编写视图元素。这个文件的作用包括:调用应用生命周期函数、配置全局样式、配置全局的存储globalData。也就是App.vue中只能进行js以及css的编写,而不能挂载视图元素,那么是否可以在js中像使用this.$message一样使用组件呢,我想到了Vue中使用vue.prototype.$message挂载全局组件的方式。

    (1)定义一个GlobalMessage.vue组件

    自定义一个消息提示组件,text将会是我们传入的提示消息参数

    <template>
    	<div class='message-container'>
    		全局消息提示 {{text}}
    	</div>
    </template>
    
    <script></script>
    
    <style lang="scss" scoped>
    	.message-container{
    		position: fixed;		
    		top: 10%;		
    		z-index: 2000;		
    		left: 10%;		
    		width: 200px;		
    		height: 200px;		
    		background-color: red;
    	}
    </style>

    (2)新建GlobalMessage.js

    将自定义组件引入,vue.extend可以使用基础的Vue构造器,创建一个子类,参数是一个包含组件的对象。对象示例如下:

    {
    template:'',
    data(){
        return {
            属性
        }
      }
    }

    但此时创建的并非组件实例,需要通过new 方式创建组件实例,参数包括创建的组件Dom节点,组件内部属性。然后使用document.body.appendChild将组件渲染到body中,此时我们已经可以调用此方法,将自定义组件挂载到全局。

    function showMessage(text,duration){
    	const MessageDom=new MessageConstructor({
    		el:document.createElement('div'),data(){
    			return {text:text,
    			}
    		}
    	})document.body.appendChild(MessageDom.$el)
    }

    接下来我们需要将该方法挂载到vue原型上,从而能够像this.$message一样使用,我们在vue.prototype上挂载$message,并将此方法导出。

    function registryMessage(){
    	vue.prototype.$message=showMessage
    }
    export default registryMessage

    GlobalMessage.js全部代码

    import vue from "vue"
    import GlobalMessage from  './GlobalMessage.vue';
    const MessageConstructor= vue.extend(GlobalMessage)
    function showMessage(text,duration){
    	const MessageDom=new MessageConstructor({
    		el:document.createElement('div'),data(){
    			return {text:text,
    			}
    		}
    	})
    	document.body.appendChild(MessageDom.$el)
    }
    function registryMessage(){
    	vue.prototype.$message=showMessage
    }
    export default registryMessage

    (3)main.js中

    将我们抛出的方法引入,使用Vue.use进行全局注册,这样就可以愉快的使用this.$message了。

    import GlobalMessage from "./GlobalMessage.js";
    // 这里也可以直接执行 
    toastRegistry()Vue.use(GlobalMessage);

    使用

    this.$message('测试数据')

    3.小程序中如何实现

    超导马得,刚刚能够全局使用this.$message,但是又遇到一个问题,小程序中没有document,我们看uni-app官方文档:

    uni-app的js API由标准ECMAScript的js API 和 uni 扩展 API 这两部分组成。
    标准ECMAScript的js仅是最基础的js。浏览器基于它扩展了window、document、navigator等对象。小程序也基于标准js扩展了各种wx.xx、my.xx、swan.xx的API。node也扩展了fs等模块。
    uni-app基于ECMAScript扩展了uni对象,并且API命名与小程序保持兼容。
    uni-app的js代码,h5端运行于浏览器中。非h5端(包含小程序和App),Android平台运行在v8引擎中,iOS平台运行在iOS自带的jscore引擎中,都没有运行在浏览器或webview里。非H5端,不支持window、document、navigator等浏览器的js API

    uni-app的js API

    那么需求不能不完成,我们采用另外一套方案,使用vuex状态机来进行全局状态控制,将自定义组件放在需要的页面中,使用状态机来控制消息的提示内容以及展示与隐藏。注:请自行安装配置vuex。

    main.js中全局注册组件

    import GlobalMessage from '@/components/common/GlobalMessage.vue';
    Vue.component('GlobalMessage',GlobalMessage)

    在需要的页面放置GlobalMessage组件,但是我们需要每个页面都要加组件标签,实在是一个难以忍受的方式,于是在翻阅一些文档后,在jy文章中发现一个工具vue-inset-loader

    4.vue-inset-loader的使用

    我们来看该loader的提示:编译阶段在sfc模板指定位置插入自定义内容,适用于webpack构建的vue应用,常用于小程序需要全局引入组件的场景。(由于小程序没有开放根标签,没有办法在根标签下追加全局标签,所以要使用组件必须在当前页面引入组件标签),该插件刚好能够帮助我们全局追加组件标签。

    vue-inset-loader

    (1)安装

    npm install vue-inset-loader --save-dev

    (2)vue.config.js注入loader

    没有vue.config.js请新建文件。

    module: {
        rules: [
          {        
              test: /.vue$/,
            use:{       
                 loader: "vue-inset-loader"            
                 // // 针对Hbuilder工具创建的uni-app项目            
                 // loader: path.resolve(__dirname,"./node_modules/vue-inset-loader")
            }
          }
        ]
    },
    // 支持自定义pages.json文件路径
    // options: {
    //     pagesPath: path.resolve(__dirname,'./src/pages.json')
    // }

    (3)pages.json配置文件中添加insetLoader

    "insetLoader": {
        "config":{
            "message": "<GlobalMessage></GlobalMessage>",
       
        },
        // 全局配置
        "label":["confirm"],
        "rootEle":"div"
    },
    "pages": [
        {
            "path": "pages/tabbar/index/index",
            "style": {
                "navigationBarTitleText": "测试页面",
                // 单独配置,用法跟全局配置一致,优先级高于全局
                "label": ["confirm","abc"],
                "rootEle":"div"
            }
        },
    ]
    1. 配置说明

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

    总结

    虽然实现了全局消息的提示,但是在小程序中,该方法还是过于麻烦,需要在每个页面追加全局组件标签,希望大家有更好的方法能够不吝赐教。

    推荐:《uniapp教程

    以上就是聊聊使用Uniapp怎么实现全局消息提示及其组件的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:掘金社区,如有侵犯,请联系admin@php.cn删除
    专题推荐:uni-app
    上一篇:实例讲解uniapp实现多选框的全选功能 下一篇:手把手带你开发一个uni-app日历插件(并发布)
    20期PHP线上班

    相关文章推荐

    • 【活动】充值PHP中文网VIP即送云服务器• VSCode中如何开发uni-app?(教程分享)• 聊聊如何利用uniapp开发一个贪吃蛇小游戏!• mysql怎么删除unique key(唯一约束)• uni-app入门:项目创建及原生tabbar配置• 实例讲解uniapp实现多选框的全选功能
    1/1

    PHP中文网