Andy's blog

If you always do what you've always done, you'll always get what you've always got.

0%

Vue Component(元件)-props.sync 溝通方式

參考資料


.sync VS props、emit

接下來,將透過兩組範例比較,來讓大家知道這兩種元件傳遞的方式差異在哪。

props、emit範例

範例連結
HTML部分

1
2
3
4
5
6
7
<div id="app">
<p>Parent: {{ message }}<input v-model="message"></p>
<hr>
Child:
<my-component :parent-message="message" @update="selfUpdate"></my-component>
</p>
</div>

寫法說明:我們會在子元件上註冊一個自定義update事件,當子元件update事件觸發時,則會同時觸發父元件selfUpdate事件
JavaScript部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Vue.component('my-component', {
template: `<div>
{{ parentMessage }}
<input v-model="message">
<button @click="updateText">Update</button>
</div>`,
props: {
parentMessage: String //字串型別
},
data() {
return {
message: this.parentMessage
}
},
methods: {
updateText() {
//事件名稱 value
this.$emit('update', this.message); //this.message是指子層的噢!
}
}
});

new Vue({
el: '#app',
data: {
message: 'hello'
},
methods: {
selfUpdate(val) {
this.message = val;
}
}
});

畫面如下


.sync範例

範例連結
HTML部分

1
2
3
4
5
<div id="app">
<p>Parent: {{ message }}<input v-model="message"></p>
<hr>
Child:
<my-component :parent-message.sync="message"></my-component>

寫法說明:我們可以發現到我們將child元件上的自定義事件移除了,改用:parent-message.sync="message"綁定

JavaScript部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Vue.component('my-component', {
template: `<div>
{{ synMsg }}
<input v-model="synMsg">
</div>`,
props: {
parentMessage: String
},
computed:{
synMsg:{
get(){
return this.parentMessage
},
set(val){
this.$emit('update:parentMessage',val)
}
}
}
});

new Vue({
el: '#app',
data: {
message: 'hello'
}
});

寫法說明:
1.原本在子元件中用methods來觸發事件,但使用語法糖後改用computed屬性來進行同步
2.並且把new Vue實體中的methods方法也移除

畫面如下:

小結論

OK,我們介紹完.sync 修飾符的使用方法,我們來聊聊為何會稱.sync為語法糖

從.sync範例中,我們依然可以發現父層元件,依舊透過props將父層資料message傳遞進來子元件。而在元件中,我們依然透過this.$emit來觸發事件,達到外層資料也同步更新的目的。

這其中最大的差別就是在於,父層元件中 parent-message.sync 其實是

1
v-bind:parent-message=”message” v-on:update:parentMessage=”parentMessage = $event”

的縮寫。