props/$emit、v-model、.sync的適用場景 -- vue元件通訊系列
vue元件的資料通訊方式很多,本篇著重講props/$emit
,神助是v-model/.sync
語法糖。
TL;DR
- props/$emit是父子元件最常用的通訊方式,而v-model、.sync只是其語法糖
- 子元件只是單一的修改某個父元件值的話,表單類元件使用
v-model
語法糖 - 子元件只是單一的修改某個父元件值的話,非表單類元件使用
sync
語法糖 - 複雜邏輯還是老老實實
props/$emit
其實語法糖只是在父元件用的時候更加方便,而子元件該咋樣還是咋樣。
props/$emit
子元件想要顯示父元件的資料,就props
。 子元件想要改變父元件的資料,就$emit
。
留意的點:
- 子元件props裡定義的屬性名和父元件裡的一一對應,注意父元件使用屬性的時候用羊肉串格式
- 父元件的監聽事件名和子元件的觸發事件名必須一模一樣
- 子元件觸發事件的時候,傳過來的引數,父元件可以用
$event
接收
v-model語法糖
v-model是屬性value和事件input的語法糖。
沒有語法糖的時候,這樣寫
用v-model的話,父元件就可以少了監聽事件,用起來更加方便
v-model的語法糖有其侷限性:
- 適用於:觸發事件返回的值 正是 屬性要改的值,一般是單一屬性。比如觸發事件返回的值正好就是提title的新值
- 更多邏輯的話,就不適用了
- 更適用於:表單類的元件,因為屬性和事件預設是
value
和input
當然特定情況下,可以修改v-model的預設屬性,但可讀性就不是很好。
export default {
name:'ListItem',
model:{
prop:'title',
input:'changeTitle'
}
}
複製程式碼
.sync語法糖
.sync這個語法糖,同樣適用於觸發事件返回的值 正是 屬性要改的值,可讀性要強一些,可以用於非表單類的元件。 .sync語法糖預設是 屬性xxx和事件update:xxx
沒有語法糖的時候,這樣寫
用.sync的話,父元件仍然可以少監聽事件,用起來更加方便
sync的語法糖有其侷限性:
- 適用於:觸發事件返回的值 正是 屬性要改的值,一般是單一屬性。比如觸發事件返回的值正好就是提title的新值
- 更多邏輯的話,就不適用了
- 更適用於:非表單類的元件
總結
- props/$emit是父子元件最常用的通訊方式,而v-model、.sync只是其語法糖
- 子元件只是單一的修改某個父元件值的話,表單類元件使用
v-model
語法糖 - 子元件只是單一的修改某個父元件值的話,非表單類元件使用
sync
語法糖 - 複雜邏輯還是老老實實
props/$emit
其實語法糖只是在父元件用的時候更加方便,而子元件該咋樣還是咋樣。
程式碼
props/$emit的程式碼
List.vue
<template lang="pug">
//- 父元件
div
//- item就是傳遞給ListItem的資料,屬性是info
//- clickLike,就是監聽ListItem的clickLike事件
list-item(v-for="(item,index) in list" :key="index"
:info="item"
v-on:clickLike="change(item,$event)")
</template>
<script>
import ListItem from "@/components/ListItem";
export default {
name: "List",
components: { ListItem },
data() {
return {
list: [
{ title: "vue3來了", collects: 20 },
{ title: "憐憐來了", collects: 2000 }
]
};
},
methods: {
// 當clickLike事件發生的時候,執行此方法
// 這裡的event是ListItem傳過來的值
change(item, event) {
item.collects = event;
}
}
};
</script>
複製程式碼
DetailItem.vue
<template lang="pug">
//- 子元件
div
h2 {{info.title}}
span 喜歡數 {{info.collects}}
div
button(@click="addCollect") 喜歡
hr
</template>
<script>
export default {
name: "ListItem",
props: {
// 這裡定義父元件傳過來的屬性
info: { type: Object, default: () => ({}) }
},
methods: {
addCollect() {
// 觸發此元件的clickLike時間,並且傳一個值給父元件
this.$emit("clickLike", this.info.collects + 1);
}
}
};
</script>
複製程式碼
v-model程式碼
沒有簡寫時候的程式碼
<template lang="pug">
//- 父元件
div
list-item(:value="title" v-on:input="change")
</template>
<script>
import ListItem from "@/components/ListItem";
export default {
name: "List",
components: { ListItem },
data() {
return {
title: "憐憐來了"
};
},
methods: {
// 當clickLike事件發生的時候,執行此方法
// 這裡的event是ListItem傳過來的值
change(event) {
this.title = event;
}
}
};
</script>
複製程式碼
<template lang="pug">
//- 子元件
div {{value}}
button(@click="changeTitle") 修改標題
</template>
<script>
export default {
name: "ListItem",
props: {
value: { type: String, default: "" }
},
methods: {
changeTitle() {
this.$emit("input", "換標題啦");
}
}
};
</script>
複製程式碼
簡寫時候的父元件程式碼
<template lang="pug">
//- 父元件
div
list-item(v-model="title")
</template>
<script>
import ListItem from "@/components/ListItem";
export default {
name: "List",
components: { ListItem },
data() {
return {
title: "憐憐來了"
};
}
};
</script>
複製程式碼
.sync的程式碼
沒有簡寫的時候
<template lang="pug">
//- 父元件
div
list-item(:theme="title" v-on:update:theme="change")
</template>
<script>
import ListItem from "@/components/ListItem";
export default {
name: "List",
components: { ListItem },
data() {
return {
title: "憐憐來了"
};
},
methods: {
// 當clickLike事件發生的時候,執行此方法
// 這裡的event是ListItem傳過來的值
change(event) {
this.title = event;
}
}
};
</script>
複製程式碼
<template lang="pug">
//- 子元件
div {{theme}}
button(@click="changeTitle") 修改標題
</template>
<script>
export default {
name: "ListItem",
props: {
theme: { type: String, default: "" }
},
methods: {
changeTitle() {
this.$emit("update:theme", "換標題啦");
}
}
};
</script>
複製程式碼
簡寫的時候,父元件的程式碼
<template lang="pug">
//- 父元件
div
//- list-item(:theme="title" v-on:update:theme="change")
list-item(:theme.sync="title")
</template>
<script>
import ListItem from "@/components/ListItem";
export default {
name: "List",
components: { ListItem },
data() {
return {
title: "憐憐來了"
};
}
// methods: {
// // 當clickLike事件發生的時候,執行此方法
// // 這裡的event是ListItem傳過來的值
// change(event) {
// this.title = event;
// }
// }
};
</script>
複製程式碼
最後
如果你覺得此文對你有一丁點幫助,點個贊。或者可以加入我的開發交流群:1025263163相互學習,我們會有專業的技術答疑解惑
如果你覺得這篇文章對你有點用的話,麻煩請給我們的開源專案點點star: http://github.crmeb.net/u/defu 不勝感激 !
「其他文章」
- Vue.cli專案封裝全域性axios,封裝請求,封裝公共的api和呼叫請求的全過程
- MySQL一會兒快,一會兒慢的,我該怎麼辦?
- 【前端必知】Webpack效能優化
- 忘記 ajax,擁抱前後端一體化
- 你需要知道的 25 個 Vue 技巧
- Java記憶體分配原理精講
- Innodb到底是怎麼加鎖的
- 掌握 JavaScript 面試:什麼是純函式?
- JavaScript 位元組單位換算函式【詳解】
- 你需要知道的 19 個 console 實用除錯技巧
- 讓Java8的Stream更簡單
- Spring為啥不推薦使用@Autowired註解?
- 遞迴演算法講解
- 深入理解 Generators 函式
- props/$emit、v-model、.sync的適用場景 -- vue元件通訊系列
- 畫了20張圖,詳解瀏覽器渲染引擎工作原理
- 前端監控 SDK 的一些技術要點原理分析
- Flutter在開發中遇到的問題【滿滿乾貨】
- 深入理解 redux 資料流和非同步過程管理
- 前端常用的幾種加密方法