成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Vue $mount實(shí)戰(zhàn)--實(shí)現(xiàn)消息彈窗組件

lvzishen / 2039人閱讀

摘要:之前的項(xiàng)目一直在使用框架,中的組件使用時(shí)不需要在寫標(biāo)簽,而是使用調(diào)用。這樣在組件中就可以通過(guò)的形式來(lái)使用了參考參考了的代碼封裝組件的一些技巧

之前的項(xiàng)目一直在使用Element-UI框架,element中的Notification、Message組件使用時(shí)不需要在html寫標(biāo)簽,而是使用js調(diào)用。那時(shí)就很疑惑,為什么element ui使用this.$notifythis.$message就可以實(shí)現(xiàn)這樣的功能?
1、實(shí)現(xiàn)消息彈窗組件的幾個(gè)問(wèn)題

如何在任何組件中使用this.$message就可以顯示消息?

如何將消息的dom節(jié)點(diǎn)插入到body中?

同時(shí)出現(xiàn)多個(gè)消息彈窗時(shí),消息彈窗的z-index如何控制?

2、效果預(yù)覽

3、代碼實(shí)現(xiàn)

PMessage.vue





p-message.js

import Vue from "vue";
import PMessage from "./PMessage.vue";
import {popupManager} from "../../common/js/popup-manager";
let PMessageControl = Vue.extend(PMessage);
let count = 0;
// 存儲(chǔ)message組件實(shí)例,如需有關(guān)閉所有message的功能就需要將每個(gè)message組件都存儲(chǔ)起來(lái)
let instances = [];
const isVNode = function (node) {
  return node !== null && typeof node === "object" && Object.prototype.hasOwnProperty.call(node, "componentOptions");
};

const Message = function (options) {
  options = options || {};
  if(typeof options === "string"){
    options = {
      message: options
    };
  }
  let id = "message_" + ++count;
  let userOnClose = options.onClose;
  // PMsesage.vue銷毀時(shí)會(huì)調(diào)用傳遞進(jìn)去的onClose,而onClose的處理就是將指定id的message組件從instances中移除
  options.onClose = function (){
    Message._close(id, userOnClose);
  };
  /* 這里傳遞給PMessageControl的data不會(huì)覆蓋PMessage.vue中原有的data,而是與PMessage.vue中原有的data進(jìn)行合并,類似
   * 與mixin,包括傳遞methods、生命周期函數(shù)也是一樣 */
  let instance = new PMessageControl({
    data: options
  });
  // 傳遞vNode
  if(isVNode(instance.message)){
    instance.$slots.default = [instance.message];
    instance.message = null;
  }
  instance.id = id;
  // 渲染元素,隨后使用原生appendChild將dom插入到頁(yè)面中
  instance.$mount();
  let $el = instance.$el;
  // message彈窗的z-index由popupManager來(lái)提供
  $el.style.zIndex = popupManager.getNextZIndex();
  document.body.appendChild($el);
  // 將message顯示出來(lái)
  instance.show = true;
  console.log(instance)
  instances.push(instance);
  return instance;
};
// message簡(jiǎn)化操作
["success","error"].forEach(function (item) {
  Message[item] = options => {
    if(typeof options === "string"){
      options = {
        message: options
      }
    }
    options.type = item;
    return Message(options);
  }
});
/**
 * 從instances刪除指定message,內(nèi)部使用
 * @param id
 * @param userOnClose
 * @private
 */
Message._close = function (id, userOnClose) {
  for(var i = 0, len = instances.length; i < len; i++){
    if(instances[i].id === id){
      if(typeof userOnClose === "function"){
        userOnClose(instances[i]);
      }
      instances.splice(i, 1);
      break;
    }
  }
};
// 關(guān)閉所有message
Message.closeAll = function () {
  for(var i = instances.length - 1; i >= 0; i--){
    instances.close();
  }
};

export default Message;

popup-manager.js

let zIndex = 1000;
let hasZIndexInited = false;
const popupManager = {
  // 獲取索引
  getNextZIndex(){
    if(!hasZIndexInited){
      hasZIndexInited = true;
      return zIndex;
    }
    return zIndex++;
  }
};
export {popupManager};

p-index.js

import pMessage from "./p-message.js";
export default pMessage;

p-message.styl

.p-message{
  position: fixed;
  top: 20px;
  left: 50%;
  padding: 8px 15px;
  border-radius: 4px;
  background-color: #fff;
  color: #000;
  transform: translateX(-50%);
  transition: opacity .3s, transform .4s;
  &.message-fade-enter,
  &.message-fade-leave-to{
    opacity: 0;
    transform: translateX(-50%) translateY(-30px);
  }
  &.message-fade-enter-to,
  &.message-fade-leave{
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
  &.error{
    color: #ff3737;
  }
  .p-message-icon{ /* 使圖標(biāo)與內(nèi)容能夠垂直居中 */
    display: table-cell;
    vertical-align: middle;
    width: 64px;
    height: 45px;
    &.p-message-icon-success{
      background: url("../../assets/images/icons/message-icon/icon_success.png") no-repeat 0 0;
    }
    &.p-message-icon-error{
      background: url("../../assets/images/icons/message-icon/icon_error.png") no-repeat 0 0;
    }
  }
  .p-message-content{ /* 使圖標(biāo)與內(nèi)容能夠垂直居中 */
    display: table-cell;
    vertical-align: middle;
    padding-left: 15px;
  }
}

main.js

// 引入pMessage組件
import pMessage from "./components/p-message/p-index.js";
// 將pMessage綁定到Vue.prototype中。這樣在組件中就可以通過(guò)this.$pMessage()的形式來(lái)使用了
Vue.prototype.$pMessage = pMessage;
3、參考

參考了 Element-UImessage代碼

封裝Vue組件的一些技巧

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/103698.html

相關(guān)文章

  • 封裝Vue組件的一些技巧

    摘要:根據(jù)組件單向數(shù)據(jù)流和和事件通信機(jī)制,需要由子組件通過(guò)事件通知父組件,并在父組件中修改原始的數(shù)據(jù),完成狀態(tài)的更新。 本文同步在個(gè)人博客shymean.com上,歡迎關(guān)注 寫Vue有很長(zhǎng)一段時(shí)間了,除了常規(guī)的業(yè)務(wù)開(kāi)發(fā)之外,也應(yīng)該思考和反思一下封裝組件的正確方式。以彈窗組件為例,一種實(shí)現(xiàn)是在需要模板中引入需要彈窗展示的組件,然后通過(guò)一個(gè)flag變量來(lái)控制彈窗的組件,在業(yè)務(wù)代碼里面會(huì)充斥著冗余的彈...

    韓冰 評(píng)論0 收藏0
  • vue彈窗插件實(shí)戰(zhàn)

    摘要:組件顯示隱藏由內(nèi)部屬性控制,只暴露給外界和個(gè)方法,個(gè)方法觸發(fā)對(duì)應(yīng)的事件測(cè)試一下彈窗內(nèi)容插件化組件功能寫好了,但是這種調(diào)用方式顯得很累贅。我們寫的彈窗能不能這么方便呢,為此需要把改寫成插件。 vue做移動(dòng)端經(jīng)常碰到彈窗的需求, 這里寫一個(gè)功能簡(jiǎn)單的vue彈窗 popup.vue {{text}} 組件html結(jié)構(gòu), 外層divposition:fixed定位, 內(nèi)...

    ZweiZhao 評(píng)論0 收藏0
  • 從Dialog管理談到Vue渲染原理

    摘要:在組件內(nèi),我們觸及不到組件的模板,所以簡(jiǎn)單的在動(dòng)態(tài)模板上添加并不能完成事件監(jiān)聽(tīng)。簡(jiǎn)單來(lái)說(shuō),依賴收集是在渲染函數(shù)渲染的函數(shù)中進(jìn)行的,在中一旦通過(guò)使用了這個(gè)變量,通過(guò)這個(gè)變量的就收集到了正在執(zhí)行的渲染函數(shù)這一個(gè)依賴。 作為一個(gè)中后臺(tái)表單&表格工程師,經(jīng)常需要在一個(gè)頁(yè)面中處理多個(gè)彈窗。我自己的項(xiàng)目中,一個(gè)復(fù)雜的審核頁(yè)面中的彈窗數(shù)量超過(guò)了30個(gè),如何管理大量的彈窗就成為了一個(gè)需要考慮的問(wèn)題。 ...

    darkbug 評(píng)論0 收藏0
  • Vue.extend用法(主要用于需要 動(dòng)態(tài)渲染的組件,或者類似于window.alert() 提示

    摘要:一簡(jiǎn)單的使用主要用于需要?jiǎng)討B(tài)渲染的組件,或者類似于提示組件注意創(chuàng)建的是一個(gè)組件構(gòu)造器,而不是一個(gè)具體的組件實(shí)例屬于的全局,在實(shí)際業(yè)務(wù)開(kāi)發(fā)中我們很少使用,因?yàn)橄啾瘸S玫膶懛ㄊ褂貌襟E要更加繁瑣一些。 最近在重構(gòu)公司的項(xiàng)目,有些組件想要封裝的更靈活,例如toast、loading、messageBox等彈窗組件,模仿了mint-ui封裝此類組件的方式封裝了自己的彈窗組件; mint-UI的t...

    masturbator 評(píng)論0 收藏0
  • 手把手教你擼個(gè)vue2.0彈窗組件

    摘要:組件結(jié)構(gòu)同組件結(jié)構(gòu)通過(guò)方法獲取元素的大小及其相對(duì)于視口的位置,之后對(duì)提示信息進(jìn)行定位。可以用來(lái)進(jìn)行一些復(fù)雜帶校驗(yàn)的彈窗信息展示,也可以只用于簡(jiǎn)單信息的展示??梢酝ㄟ^(guò)屬性來(lái)顯示任意標(biāo)題,通過(guò)屬性來(lái)修改顯示區(qū)域的寬度。 手把手教你擼個(gè)vue2.0彈窗組件 在開(kāi)始之前需要了解一下開(kāi)發(fā)vue插件的前置知識(shí),推薦先看一下vue官網(wǎng)的插件介紹 預(yù)覽地址 http://haogewudi.me/k...

    mrli2016 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<