
前言
我們知道 vue 中父子組件的核心概念是單項數據流問題,props 是單項傳遞的。那究竟什么是單項數據流問題,這篇文章來總結一下關於這個知識點的學習筆記。
正文
1.父組件傳值給子組件
<div id="app">
<blog-item :title="title"></blog-item>
</div>
// 定義子組件
Vue.component("blog-item", {
props: ['title'],
data() {
return {
}
},
template: "<p>{{title}}</p>"
})
// 定義父組件
new Vue({
el: "#app",
data() {
return {
title: "msg",
}
},
})
父組件通過 :title = "title" 將值傳遞給子組件,子組件中通過 props 來接收父組件的值,然后通過插值表達式渲染在頁面中。
2.子組件的 props 類型約束問題
常見的類型約束如下:
props: { title: String, likes: Number, isPublished: Boolean, commentIds: Array, author: Object, callback: Function, contactsPromise: Promise // or any other constructor }
除了上面常見的類型外,vue 還提供了構造函數和自定義函數來自定義子組件 props 的類型。
(1)構造函數自定義類型
//兩個組件公共的自定義函數 function Person (firstName, lastName) { this.firstName = firstName this.lastName = lastName } //子組件中使用 Vue.component('blog-post', { props: { author: Person } //父組件中使用 var obj = new Person("1","2") <blog-post :author='obj'></blog-post>
上面的代碼中,首先定義一個公共的自定義構造函數,通過該構造函數來可以來創建一個對象,該實例對象有兩個屬性,分別是 firstName 和 lastName,在父組件中調用該構造函數創建一個 obj 實例並傳遞給子組件,子組件定義類型為構造函數的 prop 接收該對象。
(2)自定義函數自定義類型
// 自定義函數 Vue.component('blog-post', { props: { propsA: String,//必須是字符串類型 propsB: [String,Number],//多個可選的類型 propsC: {type:Number,default:100},//定義類型並設置默認值 // 自定義驗證函數 propsD:{ validator: function (value) { // 這個值必須匹配下列字符串中的一個 return ['success', 'warning', 'danger'].indexOf(value) !== -1 } } }
vue 中提供了非常靈活的來自定義子組件接收參數的類型,上面的代碼中通過自定義了驗證函數來約束父組件中的傳值類型。
3.單項數據流問題
單向數據流是vue 中父子組件的核心概念,props 是單向綁定的。當父組件的屬性值發生變化的時候,會傳遞給子組件發生相應的變化,從而形成一個單向下行的綁定,父組件的屬性改變會流向下行子組件中,但是反之,為了防止子組件無意間修改了父組件中的數據而影響到了其他的子組件的狀態,vue 規定了從下往上的數據流是不允許的。
當父組件的屬性改變,會傳遞給子組件,而子組件的屬性改變不會影響父組件,這樣的話可能會覺得 props 有點雞肋了,只能初始化組件的時候使用,在子組件內不能進行操作,因此我們在使用的時候經常有兩種板房去操作props:(1)定義一個局部變量,並用props 初始化它,以后操作這個局部變量。(2)定義一個計算屬性,處理props並返回。
<div id="app">
<blog-item :title="title1"></blog-item>
<blog-item :title="title2"></blog-item>
<blog-item :title="title3"></blog-item>
<hr>
<button @click='toclick'>點我</button>
</div>
// 定義子組件
Vue.component("blog-item", {
props: ['title'],
data() {
return {
}
},
template: "<p>{{title}}</p>"
})
// 父組件
new Vue({
el: "#app",
data() {
return {
title1: "111",
title2: "222",
title3: "333"
}
},
methods: {
toclick() {
this.title3 = "000"
}
}
})

<div id="app">
<blog-item :title="title"></blog-item>
</div>
// 定義子組件
Vue.component("blog-item", {
props: ['title'],
computed: {
computedTitle() {
return "computedTitle" + this.title
}
},
data() {
return {
subTitle: "subTitle" + this.title
}
},
template: "<p>{{title}}==={{subTitle}}==={{computedTitle}}</p>"
})
// 父組件
new Vue({
el: "#app",
data() {
return {
title: "111",
}
},
})

寫在最后
以上就是本文的全部內容,希望給讀者帶來些許的幫助和進步,方便的話點個關注,小白的成長踩坑之路會持續更新一些工作中常見的問題和技術點。

