vue的單項數(shù)據(jù)流
所有的 prop 都使得其父子 prop 之間形成了一個單向下行綁定:父級 prop 的更新會向下流動到子組件中,但是反過來則不行。這樣會防止從子組件意外改變父級組件的狀態(tài),從而導(dǎo)致你的應(yīng)用的數(shù)據(jù)流向難以理解。
額外的,每次父級組件發(fā)生更新時,子組件中所有的 prop 都將會刷新為最新的值。這意味著你不應(yīng)該在一個子組件內(nèi)部改變 prop。如果你這樣做了,Vue 會在瀏覽器的控制臺中發(fā)出警告。
如果是一個對象或者數(shù)組,那么當(dāng)子組件改變時,也會影響到父組件;是由于是同一個空間地址的原因;(破壞了單項數(shù)據(jù)流)
上個例子說明一下
<div id="app">
<div @click="fn">{{msg}}</div>
<son :m="msg"></son>
</div>
let vm = new Vue({
el:"#app",
data: {
msg:"hello"
},
methods:{
fn(){
this.msg = "hahaha"
}
},
components:{
son:{
data(){
return {}
},
props:["m"],
// props : 會把這個屬性放到當(dāng)前的組件的實例的屬性上;
// 通過props傳遞過來的數(shù)據(jù)也具有響應(yīng)式;但是不能再次傳遞父組件;
template:"<div @click='fn'>{{m}}</div>",
methods:{
fn(){
// 在組件的函數(shù)或者事件中,那么函數(shù)中的this指向了當(dāng)前組件的實例;
console.log(this);
console.log(this.m);
this.m = "world";
}
}
}
}
});
以上代碼雖然能夠?qū)崿F(xiàn)子組件的數(shù)據(jù)更改父組件的數(shù)據(jù),但是這樣做控制臺會發(fā)出警告:

image.png
并且做出了正確的提示
使用data屬性或者computed屬性接收一下這個prop的值,然后在做響應(yīng)的改變,并且不能和prop的值重名,像這樣:
props: ['m'],
data: function () {
return {
counter: this.m
}
}
或者這樣
props: ['m'],
computed: {
mc: function () {
return this.m.trim().toLowerCase()//這里做對于prop的值的一些處理
}
}
最后的效果是,子組件中能夠隨意使用prop的值,又不會改變父級的數(shù)據(jù),應(yīng)為用data或者computed做了一層攔截
let vm = new Vue({
el:"#app",
data: {
msg:"hello"
},
methods:{
fn(){
this.msg = "hahaha"
}
},
components:{
son:{
data(){
return {con:this.m}
},
props:["m"],
// props : 會把這個屬性放到當(dāng)前的組件的實例的屬性上;
// 通過props傳遞過來的數(shù)據(jù)也具有響應(yīng)式;但是不能再次傳遞父組件;
template:"<div @click='fn'>{{m}}<br>{{con}}</div>",
methods:{
fn(){
// 在組件的函數(shù)或者事件中,那么函數(shù)中的this指向了當(dāng)前組件的實例;
console.log(this.m);
this.con = "world";
console.log(this.con)
}
}
}
}
});
sync修飾符實現(xiàn)父子組件數(shù)據(jù)的雙向綁定
- 父組件的數(shù)據(jù)改變影響子組件數(shù)據(jù),子組件數(shù)據(jù)改變影響父組件數(shù)據(jù),本質(zhì)上父傳子數(shù)據(jù)用的props,子傳父數(shù)據(jù)用的是發(fā)布訂閱
上個例子:
<div id="app">
{{money}}
<!--綁定自定義事件的過程,就是訂閱的過程;-->
<!--叫發(fā)布訂閱的語法糖:簡寫-->
<!--<child v-bind:m="money" v-on:update:m="money=$event"></child>-->
<child :m.sync="money"></child>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
money : 400
},
components:{
child:{
data(){
return {}
},
props:["m"],
template:"<div>{{m}}<button @click='fn'>改變數(shù)據(jù)</button></div>",
methods:{
fn(){
// 希望在fn執(zhí)行時,觸發(fā)父組件身上的change方法;
this.$emit("update:m",888)
}
}
}
}
});
</script>
- 子組件中不操作props屬性,而是直接$emit事件和數(shù)據(jù),直接改變父組件的數(shù)據(jù)
<child v-bind:m="money" v-on:update:m="money=$event"></child>
$event是子組件$emit 發(fā)布的數(shù)據(jù)888
<child :m.sync="money"></child>
.sync只是update的簡寫的一個語法糖