組件是 Vue 的一個極其重要的概念。在移動端網頁開發時,Toast 組件使用也是很是頻繁的。本文便以 Toast 組件爲例,來說解 Vue 組件的部分知識點。javascript
平常開發時,咱們項目文件夾一般都是使用 vue-cli 建立的,以 單文件組件 的方式來組織代碼的。按照平日的開發流程,如今先建立一個 Toast.vue 文件。css
咱們開始關注實現 Toast 組件的一些要點:html
根據上文的分析,如今的代碼以下。vue
<template>
<transition name="toast-bounce">
<div class="toast" v-show="visible">
<p class="toast-msg">{{ msg }}</p>
</div>
</transition>
</template>
<script> export default { name: 'Toast', props: { visible: { type: Boolean, required: true }, msg: { type: String, required: true } } } </script>
<style lang="scss" scoped> // 添加過渡效果 .toast-bounce-enter, .toast-bounce-leave { opacity: 0; } .toast { box-sizing: border-box; position: fixed; max-width: 80%; left: 50%; top: 50%; padding: 20px; z-index: 99; transition: all .3s ease; transform: translate(-50%, -50%); border-radius: 10px; background: rgba(0, 0, 0, 0.7); color: #fff; text-align: center; .toast-msg { text-align: center; } } </style>複製代碼
在須要使用 Toast 組件的頁面,引入該組件,註冊以後就能使用了。java
以單文件組件引入,有幾個不方便的地方。git
相似這樣使用頻率較高的組件,最便捷的方式是經過調用一個函數來完成組件的建立,掛載以及銷燬。但而在開發項目過程當中,咱們把精力放在了組件的實現上,忽略了一些這些操做。接下來咱們將演示手動如何建立 Toast 組件,附加到 document.body 下,在顯示一段時間後,銷燬組件,再移除該元素。github
Vue 單文件的 script 標籤僅僅是導出一個包含組件選項的對象。爲了建立組件,先使用 Vue.extend 獲得一個構造器,接下來經過 new 進行實例化。這裏的構造函數有一個可選參數,類型是 Object,能夠傳入的屬性有 el,propsData等。vue-cli
import ToastConfig from './Toast.vue'
// 構造器
const ToastConstructor = Vue.extend(ToastConfig)
// 經過 new 建立組件
const instance = new ToastConstructor()複製代碼
Toast 組件在建立時,兩個 prop: visible, msg 必需要傳入。在 new 實例化時,配置 propsData 參數來設置組件所需的 prop。element-ui
const instance = new ToastConstructor({
propsData: {
msg: 'msg',
visible: false
}
})複製代碼
組件建立與掛載是兩個不一樣的概念,組件建立時,掛載階段還沒開始,DOM 元素中不含該節點。在 掛載 了以後,纔會被瀏覽器渲染。
在建立實例時,不但要設置 propsData屬性,還要設置掛載點 el 屬性,而且將組件附在 document.body 以後。api
const instance = new ToastConstructor({
el: document.createElement('div'),
propsData: {,
msg: 'msg',
visible: false
}
})
// 組件建立成功以後掛載
document.body.appendChild(instance.$el)複製代碼
掛載以後,顯示 toast 組件。再開啓一個定時器,在 3s 以後隱藏組件。
Vue.nextTick(() => {
instance.visible = true
setTimeout(() => {
instance.close()
}, 3000)
})複製代碼
Toast 組件隱藏的動畫結束時,觸發 transitionend 事件。instance.$el 返回組件的根元素,監聽該元素的 transitionend 事件,在回調函數中 銷燬 組件,同時從DOM樹中移除。
// 在 ToastConstructor 上添加兩個銷燬組件與移除DOM元素的函數
// 隱藏組件
ToastConstructor.prototype.close = function () {
this.visible = false
this.$el.addEventListener('transitionend', this.destroyeInstance.bind(this))
}
// 銷燬組件,移除DOM元素
ToastConstructor.prototype.destroyeInstance = function () {
this.$destroy(true)
this.$el.removeEventListener('transitionend', this.destroyeInstance)
this.$el.parentNode.removeChild(this.$el)
}複製代碼
完整代碼片斷點擊 這裏。
若是在短期頻繁調用 toast 函數,document.body 下面存在多個 toast 組件,後一個會覆蓋前一個。考慮到移動端的特色,咱們但願在同一個時間點上,不論 toast 函數調用有多頻繁,document.body 只有會有一個 toast 組件。
接下來的調整思路大體以下:
代碼須要進行一些的調整。
// 在函數以外,定義兩個變量
// 組件銷燬時,instance 也要置爲 null
let instance = null
let timer = null
function toast (msg = '默認信息') {
// 判斷 instance 是否存在
if (instance) {
instance.visible = true
instance.msg = msg
if (timer) {
clearInterval(timer)
}
instance.$el.removeEventListener('transitionend', instance.destroyeInstance)
} else {
//...
}
// ...
}複製代碼
完整代碼片斷點擊 這裏。
固然咱們也能夠再更進一步,把 toast 函數註冊爲 Vue 插件,在須要的地方經過 this.$toast
調用便可。element-ui 的 message,vux 的 Toast 都支持插件方式調用。
跟一些成熟的 Vue ui 庫,例如:mint-ui 的 Toast 組件相比,如今的 Toast 組件不足之處不少。但經過編寫一個極其簡單的 Toast 組件,瞭解到 Vue 組件的部分概念,知道了到如何手動建立,銷燬組件,如何結合 transition 製做一些簡單的動畫,有助於咱們更好的理解 Vue 組件的思想 ,並且之後在使用第三方庫的一些組件時,能大體知曉其原理。