首頁  >  文章  >  web前端  >  聊聊使用Uniapp怎麼實現全域訊息提示及其元件

聊聊使用Uniapp怎麼實現全域訊息提示及其元件

青灯夜游
青灯夜游轉載
2022-06-22 18:24:216653瀏覽

Uniapp中怎麼實作全域訊息提示及其元件?以下這篇文章跟大家介紹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=&#39;message-container&#39;>
		全局消息提示 {{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:&#39;&#39;,
data(){
    return {
        属性
    }
  }
}

但此時建立的並非元件實例,需要透過new 方式建立元件實例,參數包含建立的元件Dom節點,元件內部屬性。然後使用document.body.appendChild將元件渲染到body中,此時我們已經可以呼叫此方法,將自訂元件掛載到全域。

function showMessage(text,duration){
	const MessageDom=new MessageConstructor({
		el:document.createElement(&#39;div&#39;),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(&#39;测试数据&#39;)

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,&#39;./src/pages.json&#39;)
// }

(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. 配置说明
  • config (default: {}) 定义标签名称和内容的键值对
  • label(default: []) 需要全局引入的标签,打包后会在所有页面引入此标签
  • rootEle(default: "div") 根元素的标签类型,缺省值为div,支持正则,比如匹配任意标签 ".*"

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

总结

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

推荐:《uniapp教程

以上是聊聊使用Uniapp怎麼實現全域訊息提示及其元件的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除