Custom Event 客製化事件
NIKEDIN 2020-10-05 component組件元件emitvmodel傳子傳父
# 命名事件(傳父 $emit
)
如果組件想要修改資料,只能透過事件 來驅動父層(資料源)來修改,不可以直接由組件修改! 單向資料流
# 範列
# 使用方式
組件
組件 props
接收 父層 的資料,
如果要修改資料的話,要在事件上使用 $emit
this.$emit(父層監聽的事件名稱
, 參數
)
<template>
<div>
<p>{{ msg }}</p>
<button @click="changeText">修改文字</button>
</div>
</template>
<script>
export default {
props: {
msg: {
type: String,
requied: true,
},
},
methods: {
changeText() {
this.$emit('change-text', 'From component text')
},
},
}
</script>
父層
在屬性上接收子層 打過來的事件,使用 @監聽事件名稱="父層執行的事件"
再利用本地的事件,來修改資料!
<template>
<CustomEvent :msg="message" @change-text="change" />
</template>
<script>
export default {
data: () => ({
message: 'From App text',
}),
methods: {
change(text) {
this.message = text
},
},
}
</script>
只能從資料的來源,來修改資料,不可以接收資料的組件修改。
# 雙向綁定 v-model
除了可以使用 $emit
讓子層傳遞事件來修改父層的資料外,也可以使用 v-model
來讓 子層 與 父層 同步資料!
同時,你也不需要像一般的 $emit
要在 父層
綁定欲接收的事件屬性
# 範例
# 使用方式
父層
將資料以
v-model
綁至組件 (傳遞至組件內部)<template> <div id="app"> <p>父層的資料: {{ name }}</p> <!-- 使用 v-model 綁定資料 --> <CustomEvent v-model="name" /> </div> </template> <script> import CustomEvent from './components/CustomEvent' export default { name: 'App', components: { CustomEvent, }, data: () => ({ name: 'naiky', }), } </script>
子層 CustomEvent.vue
以
model
參數接下 父層 傳遞的資料prop
定義在 組件 中,資料的變數名稱
event
定義欲修改 父層 資料的事件名稱
(只能用kebab-case
命名)
props
定義此prop
資料的資料格式- 索引為
變數名稱
- 索引為
雙向綁定 this.$emit(
事件名稱
,傳送資料
)傳送資料
將會直接替換 父層 的資源<template> <div class="event"> <div> 使用者名稱: <h4>{{ name }}</h4> </div> <input placeholder="輸入想要修改父層的資料" @keypress.enter="submit" type="text" v-model="newName" /> <button @click="submit">修改</button> </div> </template> <script> export default { data: () => ({ newName: '', }), // ------------- 宣告綁定變數與綁定事件 model: { prop: 'name', event: 'edit-name', }, // ------------- 資料格式 props: { name: String, }, // ------------- 執行綁定事件 methods: { submit() { this.$emit('edit-name', this.newName) }, }, } </script>
注意
就算在 model
已經宣告資料的變數,仍需要在 props
宣告資料的格式! 這是必須的!
# 雙向綁定 .sync
v-model
可以雙向綁定一個 prop
,而 .sync
是可以同是綁定多個資料!
父層 屬性傳遞資料時,加上
.sync
<text-document v-bind:title.sync="doc.title"></text-document>
子層 事件名稱使用 $emit(
update:資料名稱
,新資料
)this.$emit('update:title', newTitle)
注意
在使用.sync
的時候,只能是一個變數,不能再經過運算!
v-bind:title.sync=”doc.title + ‘!’”
這樣是會失效的!