本篇文章給大家帶來的內容是關於Vue.js組件庫事件系統的設計過程(代碼),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所協助。
我們拿 input-number 為例:
@ 是 v-on 指令的簡寫,用來綁定事件監聽器:
<InputNumber @on-change="change" :max="10" :min="1" v-model="value1"></InputNumber>
我們使用組件的時候,會註冊了一個自訂
的事件:
methods: { change (v) { console.log(v) }}
在組件內部觸發的方式也很簡單:
調用了
$emit
來觸發當前執行個體上的事件,事件名為
on-change
this.$emit('on-change', val);
那思路來了,如果 InputNumber
外層嵌套在了某一個 FormItem
組件裡面,事件之間的互相調用也是類似的,只是多了個假設:
嵌套關係,可能有多級父子
像 element
和 iview
多設計了一個 mixins
,裡面提供了一個方法:dispatch
它接受 3
個參數:
componentName 組件名
eventName 自訂事件名稱
params 事件傳遞的參數
dispatch(componentName, eventName, params) {}
比如類似 input-number
,很多這種表單內嵌的組件,都會設計和 FormItem
的互動:
this.dispatch('FormItem', 'on-form-change', val);
我們在設計 FormItem
組件的時候,注意:
export default { name: 'FormItem'}
然後註冊一個自訂事件,方式也是一樣的:
<Form-item @on-form-change="test"></Form-item>
我們來看一下 dispatch 函數的內部:
思路是一層一層往上找父元素:
$parent -- 父執行個體
$root -- 組件樹的根 Vue 執行個體
var parent = this.$parent || this.$root;
擷取父組件的 name:
var name = parent.$options.name;
開始迴圈判斷:
while (parent && (!name || name !== componentName)) { // ...}
比如上面的input-number
內部調用了 dispatch,傳入了參數,就是一直找父元素 name
為 FormItem
的
在 while 的內部:
接著找它的父樣本,然後擷取 name
parent = parent.$parent;if (parent) { name = parent.$options.name;}
最終如果找到了:
和最開始觸發自訂事件是一樣的:$emit
if (parent) { parent.$emit.apply(parent, [eventName].concat(params));}