Vue3手冊譯稿 - 深入元件 - 自定義事件
阿新 • • 發佈:2021-03-15
> 本章節需要掌握元件基礎
> emit我譯成發射,覺得發射這個詞比較形象的形容將子元件事件發射出來的一個動作。
### **事件名**
像元件和`props`,事件名也會進行自動轉換,如果你在子元件裡發射一個駝峰命名的事件,你就可以在父元件中新增一個短橫線分隔的監聽:
~~~
this.$emit('myEvent')
~~~
~~~html
~~~
因為有`props`情形存在,模板內DOM議使用短橫線分隔命名方式。如果你使用字串模板,則不存在這個限制。
### **自定義事件定義**
> [Vue School自定義事件視訊教程](https://vueschool.io/lessons/defining-custom-events-emits?friend=vuejs)
自定義事件發射(請子元件傳遞到父元件)可以通過`emits`選項:
~~~
app.component('custom-form', {
emits: ['inFocus', 'submit']
})
~~~
當在`emits`中定義了一個原生事件(如`click`)時,元件事件將會代替原生事件監聽。
> 提示
> 推薦定義所有已發射的事件,以便記錄元件是如何工作的
### **驗證已射事件**
同`prop`型別驗證一樣,一個已發射事件如果通過物件語法而不是陣列語法,也可以被驗證。
新增一個驗證,事件會分配一個函式來接收引數,並傳遞給`$emit`呼叫,返回一個布林值來確認事件是否有效。
~~~
app.component('custom-form', {
emits: {
// 無驗證
click: null,
// 驗證提交事件
submit: ({ email, password }) => {
if (email && password) {
return true
} else {
console.warn('不合法的 submit 事件載入!')
return false
}
}
},
methods: {
submitForm() {
this.$emit('submit', { email, password })
}
}
})
~~~
## `v-model`引數
預設元件的`v-model`使用`modelValue`作為prop和`update:modelValue`作為事件。我們可以傳遞一個引數給`v-model`修改這些名稱:
~~~html
~~~
~~~
app.component('my-component', {
props: {
title: String
},
emits: ['update:title'],
template: `
`
})
~~~
在這個案例中,子元件會同步接收`title`prop,發射`update:title`事件:
~~~
app.component('my-component', {
props: {
title: String
},
emits: ['update:title'],
template: `
`
})
~~~
~~~html
~~~
## 多`v-model`繫結
正如前面所學習`v-model`引數,我們可以為同一個元件例項新增多個v-model引數。
每個`v-model`可以與不同的`prop`相同步,元件不需要額外的選項:
~~~html
~~~
~~~
app.component('user-name', {
props: {
firstName: String,
lastName: String
},
emits: ['update:firstName', 'update:lastName'],
template: `
`
})
~~~
我們來寫一個完整點的例子,實現一個區號-座機輸入元件,結果如下圖:
![image](https://img2020.cnblogs.com/blog/27832/202103/27832-20210315195130762-209937118.png)
程式碼如下:
~~~html
component v-model
~~~
~~~
app.component('my-component', {
props: {
modelValue: String,
modelModifiers: {
default: () => ({})
}
},
emits: ['update:modelValue'],
template: `
`,
created() {
console.log(this.modelModifiers) // { capitalize: true }
}
})
~~~
現在我們設定好了prop,我們檢測`modelModifiers`物件的鍵,然後通過方法處理要發射出去的值。下面我們來把輸入框的首字母轉換為大寫:
~~~html
component v-model modifiers
~~~
~~~
app.component('my-component', {
props: ['description', 'descriptionModifiers'],
emits: ['update:description'],
template: `
`,
created() {
console.log(this.descriptionModifiers) // { capitalize: true }
{{areaNumber}}-{{telNumber}}
~~~ ## 處理`v-model`修飾符 在前面我們學習輸入繫結時,`v-model`有一些內建的修飾符如`.trim`,`.number`,`.lazy`等。有些情形,你也想增加一些自定義的修飾符。 讓我們來建立一個`capitalize`修飾符,使用`v-model`繫結將輸入首字母轉換為大寫。 元件`v-model`修飾符通過`modelModifers`prop提供給元件。下面的例子,我們建立了一個含有預設為空物件 的`modelModifiers`prop元件。 注意在元件`created`生命週期勾子觸發器中,`modelModifiers`prop包含`capitalize`且值是`true` - 當它被設定在`v-model`繫結`v-model.capitalize="myText"`。 ~~~html{{ myText }}
~~~ `v-model`繫結引數,生成的prop名將會是`arg+"modelModifiers"`: ~~~html