UI組件庫中有一類特別的“組件”,它們的用法和普通的組件有區(qū)別,也有自己很明顯的特點。
用法上,比較簡單,不需要和普通組件一樣需要引入-注冊-寫標(biāo)簽,而是可以隨時隨地,直接通過類似 this.$***() 這樣的形式。
另外明顯的一個特點就是,這類組件很常用,結(jié)構(gòu)比較簡單,所以常見的一些對話框,通知條之類的都會封裝成插件,下面就一起來實現(xiàn)一個簡單的消息提示插件吧。
一、先說說用法
// 方式1
this.$message("這是一個提示信息");
// 方式2,根據(jù) Bulma 的支持情況,我們支持 8 種不同樣式的 Message,'dark', 'primary', 'link', 'info', 'success', 'warning', 'danger'
this.$message.success("這是一個成功提示");
// 方式3
this.$message({
type: "danger",
content: "操作失敗了",
});
上面是該插件的三種使用方式,需要我們在實現(xiàn)插件功能的時候考慮到
二、組件結(jié)構(gòu)
這里我們采用和 Element 不同的實現(xiàn)思路,如果你也研究過 Element 源碼的話,會發(fā)現(xiàn)對 Message 盒子位置的計算比較麻煩(通過定位的方式),而且每次有 Message 盒子消失都要重新計算相關(guān)其它盒子的位置。
這里,我的思路是設(shè)置一個父盒子,定位到合適的位置(頁面水平居中,依次垂直排列),每一個 Message 盒子都沒有定位,用 margin 設(shè)置盒子之間的距離,一旦有盒子消失,根據(jù)瀏覽器文檔流的規(guī)則,其它相關(guān)盒子都會自己填充剩下的位置,而不需要其它操作。
<template>
<article class="message" :class="[type?'is-'+type:'']">
<div class="message-body">{{content}}</div>
</article>
</template>
上面是 Message 組件的結(jié)構(gòu)和樣式,由 Bulma 提供,不解釋
組件還要處理的事項:
- 設(shè)置父盒子樣式,因其被動態(tài)生成并追加到頁面,組件內(nèi) <style> 不加 scoped
- 設(shè)置定時器,并按時回調(diào) remove() 從頁面刪除相關(guān)節(jié)點
三、封裝組件成插件
import Vue from 'vue'
import Message from './Message'
const MessageConstructor = Vue.extend(Message)
let messageWrApper = null
const ZxMessage = {
install(options, type) {
if (typeof options == 'function') return
if (typeof options == 'string') {
options = {
content: options
}
if (type) {
options.type = type
}
}
options.remove = function (comp) {
messageWrapper.removeChild(comp.$el)
if (messageWrapper.children.length == 0) {
document.body.removeChild(messageWrapper)
messageWrapper = null
}
}
let instance = new MessageConstructor({
data: options
}).$mount()
if (!messageWrapper) {
messageWrapper = document.createElement('div')
messageWrapper.className = 'zx-message-wrapper'
document.body.appendChild(messageWrapper)
}
messageWrapper.appendChild(instance.$el)
}
}
Vue.prototype.$message = ZxMessage.install;
['dark', 'primary', 'link', 'info', 'success', 'warning', 'danger'].forEach(type => {
Vue.prototype.$message[type] = content => {
return Vue.prototype.$message(content, type)
}
})
export default ZxMessage
提示:
- 處理初始情況
- 組件狀態(tài)覆蓋合并
- 無 Message 盒子時,父盒子的處理
- 保證父盒子唯一
- 多種類型 Message 支持
- 3種調(diào)用方式支持
具體過程分享的時候已經(jīng)很清楚的說了,還有不清楚的地方找組長或者找我吧
祝編程愉快!
END