
一個(gè)組件的封裝,基本上都會(huì)用到數(shù)據(jù)管理。就像你編寫一個(gè)函數(shù),有時(shí)候需要入?yún)ⅲ瘮?shù)內(nèi)部擁有變量,然后有一個(gè)返回結(jié)果。對(duì)應(yīng)到組件里面,有時(shí)也會(huì)帶入?yún)?shù)(props),內(nèi)部變量(data)和返回結(jié)果(ui)。偽代碼如下:
function(props) {
let data = {...};
// 通過外部參數(shù)和內(nèi)部數(shù)據(jù)返回一個(gè)UI視圖
return render(props, data)
}
接下來(lái)我們看看props和data的使用方式。
Props
props 作為外部參數(shù)傳遞給組件,一般可以傳入多種類型,例如字符串,布爾類型,數(shù)組,對(duì)象等。為了更好的規(guī)范傳入的props,有時(shí)也可以在組件內(nèi)部規(guī)定好傳入組件的props的數(shù)據(jù)類型。在組件內(nèi)部使用時(shí),就像函數(shù)一樣,雖然js是解釋性語(yǔ)言,修改props也不會(huì)報(bào)錯(cuò),但是不要在組件內(nèi)部修改props的值。
所以,vue中使用props的數(shù)據(jù)都是單向傳遞的,父-> 子,每當(dāng)父組件的porps變化時(shí),子組件也會(huì)重新渲染。
props核心概念
- Prop 的大小寫命名
- 單向數(shù)據(jù)流
- props數(shù)據(jù)類型
- 靜態(tài)或者動(dòng)態(tài)的porps
- props數(shù)據(jù)類型驗(yàn)證,必填,設(shè)置默認(rèn)值等
Prop 的大小寫命名
先看看簡(jiǎn)單的Prop的大小寫命名,由于HTML 中的 attribute 名是大小寫不敏感的,所以瀏覽器會(huì)把所有大寫字符解釋為小寫字符。這意味著當(dāng)你使用 DOM 中的模板時(shí),camelCase (駝峰命名法) 的 prop 名需要使用其等價(jià)的 kebab-case (短橫線分隔命名) 命名。
示例:
App.vue
<template>
<Props1 firstName="中華" last-name="張"></Props1>
</template>
<script>
import Props1 from '@/components/Props/Props1'
export default {
name: 'App',
components: {
Props1,
}
}
</script>
Props1.vue
/**
* 測(cè)試props的命名
*/
<template>
<div class="name-box">
<div class="first-name">{{ firstName }}</div>
<div class="last-name">{{ last-name }}</div>
</div>
</template>
<script>
import { defineComponent } from '@vue/composition-api'
export default defineComponent({
props: [ 'firstName', 'last-name'],
})
</script>
<style scoped>
</style>
這里先不做轉(zhuǎn)換看看會(huì)出什么結(jié)果:

注意:如果我們不轉(zhuǎn)換,這里就得不到值!


單向數(shù)據(jù)流
prop傳遞方向:parent -> child
所有的 prop 都使得其父子 prop 之間形成了一個(gè)單向下行綁定:父級(jí) prop 的更新會(huì)向下流動(dòng)到子組件中,但是反過來(lái)則不行。這樣會(huì)防止從子組件意外變更父級(jí)組件的狀態(tài),從而導(dǎo)致你的應(yīng)用的數(shù)據(jù)流向難以理解。
另外,每次父級(jí)組件發(fā)生變更時(shí),子組件中所有的 prop 都將會(huì)刷新為最新的值。這意味著你不應(yīng)該在一個(gè)子組件內(nèi)部改變 prop。如果你這樣做了,Vue 會(huì)在瀏覽器的控制臺(tái)中發(fā)出警告。
靜態(tài)或者動(dòng)態(tài)的porps
props可以傳遞動(dòng)態(tài)的,也可以傳遞靜態(tài)的, 如下示例,firstName就是使用動(dòng)態(tài)方式傳遞的,你可以將data的firstName改變,界面也會(huì)重新渲染。
<template>
<Props1 :firstName="firstName" last-name="張"></Props1>
</template>
<script>
import Props1 from '@/components/Props/Props1'
export default {
name: 'App',
components: {
Props1,
},
data() {
return {
firstName: '中華'
}
}
}
</script>
props數(shù)據(jù)類型 && props數(shù)據(jù)類型驗(yàn)證,必填,設(shè)置默認(rèn)值等
在上面的示例中,我們可以利用props將數(shù)據(jù)從父組件傳遞給子組件,props的數(shù)據(jù)類型除了上面的String類型,還可以傳遞的類型有:Number、Boolean、Array、Object、Function、Promise等。
我們?cè)谧咏M件中定義好了將要接收的props的名字,可是有時(shí)我們需要定義下props的類型該怎么做呢,或者有些需要必填、設(shè)置默認(rèn)值又該怎么操作呢?
接下來(lái)看個(gè)小例子:
App.vue
<template>
<Props1 firstName="中華" last-name="張" :interests="interests"></Props1>
</template>
<script>
import Props1 from '@/components/Props/Props1'
export default {
name: 'App',
components: {
Props1,
},
data() {
return {
interests: "read"
}
}
}
</script>
Props1.vue
/**
* 測(cè)試props的命名
*/
<template>
<div class="name-box">
<div class="first-name">firstName: {{ firstName }}</div>
<div class="last-name">lastName: {{ lastName }}</div>
<div class="age">age: {{ age }}</div>
<div class="interests">interests: {{ interests }}</div>
</div>
</template>
<script>
import { defineComponent } from '@vue/composition-api'
export default defineComponent({
props: {
firstName: {
type: String,
required: true,
},
lastName: [String, Function], // 可以有多種類型
age: {
type: Number,
default: 18,
},
interests: {
type:String,
validator: function (value) {
return value == 'read'; // 如果傳的值不是read,在控制臺(tái)會(huì)彈出警告,在程序上不會(huì)看出區(qū)別
}
}
},
})
</script>
<style scoped>
</style>

data
組件的數(shù)據(jù)管理,出來(lái)外部傳入的數(shù)據(jù),還有內(nèi)部的數(shù)據(jù),就是data。
組件的 data 選項(xiàng)是一個(gè)函數(shù)。Vue 在創(chuàng)建新組件實(shí)例的過程中調(diào)用此函數(shù)。它應(yīng)該返回一個(gè)對(duì)象,然后 Vue 會(huì)通過響應(yīng)性系統(tǒng)將其包裹起來(lái),并以 $data 的形式存儲(chǔ)在組件實(shí)例中。
示例:
<template>
<div class="container">
初始值是: {{ initCount }}
點(diǎn)擊的次數(shù): {{ count }}
<button @click="clickBtn">按鈕</button>
</div>
</template>
<script>
export default {
props: ['initCount'],
data() {
return {
count: 0
}
},
methods: {
clickBtn() {
this.count++;
}
}
}
</script>
<style scoped>
button {
color: red;
border: 1px solid #909090;
}
</style>
在上面的例子中,在data中定義了一個(gè)count,作為內(nèi)部數(shù)據(jù)管理,顯示在界面上。