日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

设计模式在vue中的应用(五)

發布時間:2025/3/8 vue 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式在vue中的应用(五) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

目錄整理:
設計模式在vue中的應用(一)
設計模式在vue中的應用(二)
設計模式在vue中的應用(三)
設計模式在vue中的應用(四)
設計模式在vue中的應用(五)
設計模式在vue中的應用(六)

為什么要寫這些文章呢。正如設計模式(Design Pattern)是一套被反復使用、多數人知曉的、經過分類的、代碼設計經驗的總結(來自百度百科)一樣,也是想通過分享一些工作中的積累與大家探討設計模式的魅力所在。
在這個系列文章中為了輔助說明引入的應用場景都是工作中真實的應用場景,當然無法覆蓋全面,但以此類推也覆蓋到了常見的業務場景



這一篇要講的可能和之前有點區別,前面幾篇要達到我們的目的不得不造出很多對象(組件),而本文的主角是讓我們減少對象——享元模式。
定義(來自網絡):

享元模式使用共享技術實現相同或者相似對象的重用。也就是說實現相同或者相似對象的代碼共享。

使用場景(來自百度百科):

如果一個應用程序使用了大量的對象,而這些對象造成了很大的存儲開銷的時候就可以考慮是否可以使用享元模式。

一、需求

截圖來自iView官方文檔(Message組件)

Message組件相信大家不會陌生,不知道大家有沒有親自實現過

二、需求分析

Message組件有以下幾個特點:

  • 交互方式一樣
  • 有三種類型:success、warning、error,對應三種不用的頁面效果:提示icon、背景樣式、字體樣式
  • 接收一段提示文字

可以知道:

交互方式——彈出、隱藏,由共享對象所擁有

提示icon、背景樣式、字體樣式提供接口可配置

使用api統一

三、設計實現

常規使用方式this.$Message.success()、this.$Message.warning()、this.$Message.error()所以我們需要以vue插件的形式擴展vue的prototype

//Message.js 偽代碼 export default {install (Vue) {// 擴展Vue的`prototype`Vue.prototype.$Message = {success (text) {// 通常我們可能如下操作,每次new一個新的組件對象const Dialog = new Vue({...})document.body.appendChild(Dialog.$el)},warning (text) {// 同上,new一個新的組件對象const Dialog = new Vue({...})document.body.appendChild(Dialog.$el)},error (text) {// 同上,new一個新的組件對象const Dialog = new Vue({...})document.body.appendChild(Dialog.$el)}}} } 復制代碼

如上例子所示每次使用Message組件都需new一個Dialog出來,下面我們使用享元模式的思想達到減少組件對象的目的

//Message.js 偽代碼 export default {install (Vue) {// 在使用插件Vue.use(Message)時實例化一個Dialog組件對象const Dialog = new Vue({data () {return {icon: '',fontStyle: '',backgroundStyle: '',text: ''}}...})// 擴展Vue的`prototype`Vue.prototype.$Message = {success (text) {// 改變Dialog的data.xx的值觸發Dialog的更新Dialog.icon = successIconDialog.fontStyle = successFontStyleDialog.backgroundStyle = successBackgroundStyleDialog.text = text// 獲取Dialog的最新DOM添加到body標簽中document.body.appendChild(Dialog.$el)},warning (text) {// 同上...document.body.appendChild(Dialog.$el)},error (text) {// 同上...document.body.appendChild(Dialog.$el)}}} } 復制代碼

四、結果

都說做事是結果導向的,現在看看我們的設計得到了什么結果

Dialog只會在項目初始化時被new一次,每次使用Message組件通過改變Dialog的狀態獲取組件DOM,其實很容易知道new一個組件的成本要比一個組件的更新成本高很多

與常規的實現方案相比缺點是就算沒使用也會執行new Dialog()并占用內存

五、附完整實現(示例)

如有bug還請見諒隨手寫的

import './index.scss'let zIndex = 2001;export default {install (Vue) {const Dialog = new Vue({data () {return {text: '這是一個提示',icon: 'icon-waiting',iconColor: '#308AFE',background: '#ddd'}},render (h) {zIndex++const selfStyle = {background: this.background,zIndex}return h('div',{class: 'm-message',style: selfStyle},[h('i', {style: {marginRight: '8px', color: this.iconColor},class: `iconfont ${this.icon}`}),this.text])}}).$mount()function appendDialog(message, icon, iconColor, bgColor, time = 3) {Dialog.text = messageDialog.icon = iconDialog.iconColor = iconColorDialog.background = bgColorlet timer = ''let element = document.createElement('div')Dialog.$nextTick(() => {element = Dialog.$el.cloneNode(true)document.body.appendChild(element)})if(time > 0) {timer = setTimeout(() => {element.classList.add('outer')setTimeout(() => {document.body.removeChild(element)}, 500);clearTimeout(timer)}, time * 1000);}}Vue.prototype.$message = {tips (message, time) {appendDialog(message, 'icon-waiting', '#308AFE', '#ADD8F7', time)},warning(message, time) {appendDialog(message, 'icon-warn', '#FFAF0D', '#FCCCA7', time)},success(message, time) {appendDialog(message, 'icon-success', '#36B37E', '#A7E1C4', time)},error(message, time) {appendDialog(message, 'icon-error', '#E95B5B', '#FFF4F4', time)},destory() {document.querySelectorAll('.m-message').forEach(ele => ele.remove())}}} } 復制代碼

六、總結

回想一下在講解講享元模式時大多會例舉的一個場景

有男女衣服各50套,現在要給這些衣服拍照怎么辦呢?土豪做法:new 100個模特對象一人穿一套慢慢拍,有錢任性(內存占有率高) 理性做法:new 一個男模特和一個女模特拍完一套換一套接著拍(暴露一個換衣服的接口),也沒差,主要是省錢(對象從100個減少為2個) 復制代碼

熟悉設計模式同學的可能覺得這個場景不太好,我認同你的觀點,不過用來學習享元模式個人覺得還能接受。
Message組件的具體實現方案不拒絕也不推薦本文的方式(哈哈哈~)

更新:發現elemnet-ui的MessageBox組件就是類似的思路傳送門


本文實現同樣適用于react,為什么文章以vue做題?vue的template讓我們在理解一些概念的時候可能會有點不適應,而react的jsx可以看做就是在寫JavaScript對各種概念實現更靈活
友情提示:設計模式在vue中的應用應該會寫一個系列,喜歡的同學記得關注下

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的设计模式在vue中的应用(五)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。