咱們拿 input-number
爲例:app
@
是 v-on
指令的簡寫,用來綁定事件監聽器
:iview
<InputNumber @on-change="change" :max="10" :min="1" v-model="value1"> </InputNumber>
咱們使用組件的時候,會註冊了一個自定義
的事件:函數
methods: { change (v) { console.log(v) } }
在組件內部觸發的方式也很簡單:this
調用了$emit
來觸發當前實例上的事件,事件名爲on-change
this.$emit('on-change', val);
那思路來了,若是 InputNumber
外層嵌套在了某一個 FormItem
組件裏面,事件之間的互相調用也是相似的,只是多了個假設:spa
嵌套關係,可能有多級父子
像 element
和 iview
多設計了一個 mixins
,裏面提供了一個方法:dispatch
設計
它接受 3
個參數:code
dispatch(componentName, eventName, params) { }
好比相似 input-number
,不少這種表單內嵌的組件,都會設計和 FormItem
的互動:component
this.dispatch('FormItem', 'on-form-change', val);
咱們在設計 FormItem
組件的時候,注意:orm
export default { name: 'FormItem' }
而後註冊一個自定義事件,方式也是同樣的:事件
<Form-item @on-form-change="test"> </Form-item>
咱們來看一下 dispatch 函數的內部:
思路是一層一層往上找父元素:
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)); }