前言
我們知道 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",
}
},
})
寫在最後
以上就是本文的全部內容,希望給讀者帶來些許的幫助和進步,方便的話點個關注,小白的成長踩坑之路會持續更新一些工作中常見的問題和技術點。