Vue3:組件基礎(chǔ)(下)
Date: April 12, 2023
Sum: props驗(yàn)證、計(jì)算屬性、自定義時(shí)間、組件上的v-model、任務(wù)列表案例
目標(biāo):
能夠知道如何對(duì) props 進(jìn)行驗(yàn)證
能夠知道如何使用計(jì)算屬性
令能夠知道如何為組件自定義事件
令能夠知道如何在組件上使用 v-model
props 驗(yàn)證
- 什么是 props 驗(yàn)證
指的是:在封裝組件時(shí)對(duì)外界傳遞過來的 props 數(shù)據(jù)進(jìn)行合法性的校驗(yàn),從而防止數(shù)據(jù)不合法的問題。
使用數(shù)組類型的 props 節(jié)點(diǎn)的缺點(diǎn):無法為每個(gè) prop 指定具體的數(shù)據(jù)類型。
- 對(duì)象類型的 props 節(jié)點(diǎn)
使用對(duì)象類型的 props 節(jié)點(diǎn),可以對(duì)每個(gè) prop 進(jìn)行數(shù)據(jù)類型的校驗(yàn),示意圖如下:
- props 驗(yàn)證
對(duì)象類型的 props 節(jié)點(diǎn)提供了多種數(shù)據(jù)驗(yàn)證方案,例如:
① 基礎(chǔ)的類型檢查 ② 多個(gè)可能的類型 ③ 必填項(xiàng)校驗(yàn) ④ 屬性默認(rèn)值 ⑤ 自定義驗(yàn)證函數(shù)
3.1 基礎(chǔ)的類型檢查
可以直接為組件的 prop 屬性指定基礎(chǔ)的校驗(yàn)類型,從而防止組件的使用者為其綁定錯(cuò)誤類型的數(shù)據(jù):
3.2 多個(gè)可能的類型
如果某個(gè) prop 屬性值的類型不唯一,此時(shí)可以通過數(shù)組的形式,為其指定多個(gè)可能的類型,示例代碼如下:
3.3 必填項(xiàng)校驗(yàn)
如果組件的某個(gè) prop 屬性是必填項(xiàng),必須讓組件的使用者為其傳遞屬性的值。此時(shí),可以通過如下的方式將其設(shè)置為必填項(xiàng):
export default {
name: 'MyCount',
props: {
count: {
type: Number,
required: true //設(shè)定required
},
state: Boolean,
}
}
3.4 屬性默認(rèn)值
在封裝組件時(shí),可以為某個(gè) prop 屬性指定默認(rèn)值。示例代碼如下:
export default {
name: 'MyCount',
props: {
// 通過“配置對(duì)象”的形式,來定義 propC 屬性的“驗(yàn)證規(guī)則”
count: {
type: Number,
default: 100, // 如果使用者沒有指定 default 的值,則 count 屬性的值默認(rèn)為 100
required: true
},
state: Boolean,
}
}
3.5 自定義驗(yàn)證函數(shù)
在封裝組件時(shí),可以為 prop 屬性指定自定義的驗(yàn)證函數(shù),從而對(duì) prop 屬性的值進(jìn)行更加精確的控制:
計(jì)算屬性
- 什么是計(jì)算屬性
計(jì)算屬性本質(zhì)上就是一個(gè) function 函數(shù),它可以實(shí)時(shí)監(jiān)聽 data 中數(shù)據(jù)的變化,并 return 一個(gè)計(jì)算后的新值,供組件渲染 DOM 時(shí)使用。
- 如何聲明計(jì)算屬性
計(jì)算屬性需要以 function 函數(shù)的形式聲明到組件的 computed 選項(xiàng)中,
示例代碼如下:
<template>
<div>
<!-- 通過v-model進(jìn)行雙向數(shù)據(jù)綁定。 .number指自動(dòng)將用戶的輸入值轉(zhuǎn)為數(shù)值類型 -->
<input type="text" v-model.number="count" />
<p>{{ count }} 乘以2的值為: {{ plus }}</p>
</div>
</template>
<script>
export default {
name: 'MyCounter',
data() {
return {
count: 1,
}
},
computed: {
// 計(jì)算屬性:監(jiān)聽data中count值的變化,自動(dòng)計(jì)算出count*2之后的新值
plus() {
return this.count * 2
}
}
}
</script>
結(jié)果:
注意:計(jì)算屬性側(cè)重于得到一個(gè)計(jì)算的結(jié)果,因此計(jì)算屬性中必須有 return 返回值!
- 計(jì)算屬性的使用注意點(diǎn)
① 計(jì)算屬性必須定義在 computed 節(jié)點(diǎn)中
② 計(jì)算屬性必須是一個(gè) function 函數(shù)
③ 計(jì)算屬性必須有返回值
④ 計(jì)算屬性必須當(dāng)做普通屬性使用
比如 {{plus}}, 而非是這樣用:{{plus()}}
- 計(jì)算屬性 vs 方法
相對(duì)于方法來說,計(jì)算屬性會(huì)緩存計(jì)算的結(jié)果,只有計(jì)算屬性的依賴項(xiàng)發(fā)生變化時(shí),才會(huì)重新進(jìn)行運(yùn)算。因此計(jì)算屬性的性能更好
案例:
-
Code:
<template> <div> <!-- 通過v-model進(jìn)行雙向數(shù)據(jù)綁定。 .number指自動(dòng)將用戶的輸入值轉(zhuǎn)為數(shù)值類型 --> <input type="text" v-model.number="count" /> <p>{{ count }} 乘以2的值為: {{ plus }}</p> <p>{{ count }} 乘以2的值為: {{ plus }}</p> <p>{{ count }} 乘以2的值為: {{ plus }}</p> <hr/> <p>{{ count }} 乘以2的值為: {{ m_plus() }}</p> <p>{{ count }} 乘以2的值為: {{ m_plus() }}</p> <p>{{ count }} 乘以2的值為: {{ m_plus() }}</p> </div> </template> <script> export default { name: 'MyCounter', data() { return { count: 1, } }, computed: { // 計(jì)算屬性:監(jiān)聽data中count值的變化,自動(dòng)計(jì)算出count*2之后的新值 plus() { console.log("計(jì)算屬性被執(zhí)行了"); return this.count * 2 } }, methods: { m_plus() { console.log("方法被執(zhí)行了"); return this.count * 2 } } } </script>
效果:
注意:
計(jì)算屬性的結(jié)果會(huì)被緩存,性能好
方法的計(jì)算結(jié)果無法被緩存,性能低
5. 計(jì)算屬性案例
案例需求,使用計(jì)算屬性動(dòng)態(tài)計(jì)算:
① 已勾選的商品總個(gè)數(shù) ② 已勾選的商品總價(jià) ③ 結(jié)算按鈕的禁用狀態(tài)
-
Code:
computed: { //動(dòng)態(tài)計(jì)算出勾選水果的總數(shù)量 total() { let t = 0 this.fruitlist.forEach(x => { if(x.state) { t += x.count } }) return t }, amount() { let a = 0 this.fruitlist .filter(x => x.state) .forEach(x => { a += x.price * x.count }) return a }, isDisabled() { this.total === 0 } },
注意:
這里的this指的是當(dāng)前組件實(shí)例
computed: {
isDisabled() {
this.toal === 0
}
}
自定義事件
- 什么是自定義事件
在封裝組件時(shí),為了讓組件的使用者可以監(jiān)聽到組件內(nèi)狀態(tài)的變化,此時(shí)需要用到組件的自定義事件
注意:這里是在App.vue中監(jiān)聽MyCounter組件中數(shù)據(jù)的變化。
- 自定義事件的 3 個(gè)使用步驟
在封裝組件時(shí):
① 聲明自定義事件
② 觸發(fā)自定義事件
在使用組件時(shí):
③ 監(jiān)聽自定義事件
2.1 聲明自定義事件
開發(fā)者為自定義組件封裝的自定義事件,必須事先在 emits 節(jié)點(diǎn)中聲明,示例代碼如下:
2.2 觸發(fā)自定義事件
在 emits 節(jié)點(diǎn)下聲明的自定義事件,可以通過 this.$emit(‘自定義事件的名稱’) 方法進(jìn)行觸發(fā),示例代碼如下:
2.3 監(jiān)聽自定義事件
在使用自定義的組件時(shí),可以通過 v-on 的形式監(jiān)聽自定義事件。示例代碼如下:
3. 自定義事件傳參
在調(diào)用 this.$emit() 方法觸發(fā)自定義事件時(shí),可以通過第 2 個(gè)參數(shù)為自定義事件傳參
示例代碼如下:
//counter.vue
methods: {
add() {
this.count++
this.$emit('countChange',this.count) // 觸發(fā)自定義事件,通過第二個(gè)參數(shù)傳參
}
}
//App.vue
methods: {
getCount(val) {
console.log("觸發(fā)了 countChange 自定義事件", val);
}
},
理解:在counter組件中的$emit中傳入?yún)?shù),然后在App.vue中的methods中傳入?yún)?shù)接收即可
組件上的 v-model
1. 為什么需要在組件上使用 v-mode
v-model 是雙向數(shù)據(jù)綁定指令,當(dāng)需要維護(hù)組件內(nèi)外數(shù)據(jù)的同步時(shí),可以在組件上使用 v-model 指令。示意圖如下:
外界數(shù)據(jù)的變化會(huì)自動(dòng)同步到 counter 組件中 ; counter 組件中數(shù)據(jù)的變化,也會(huì)自動(dòng)同步到外界
理解:父組件和子組件中數(shù)據(jù)的變化會(huì)相互影響
2. 在組件上使用 v-model 的步驟
2.1 父向子傳遞數(shù)據(jù)
① 父組件通過 v-bind: 屬性綁定的形式,把數(shù)據(jù)傳遞給子組件
② 子組件中,通過 props 接收父組件傳遞過來的數(shù)據(jù)
案例:
<template>
<div>
<h1>App根組件 --- {{ count }}</h1>
<button @click="count += 1">+1</button>
<hr/>
<my-counter :number="count"></my-counter> //通過v-bind屬性將count值傳遞給number
</div>
</template>
2.2 子向父?jìng)鬟f數(shù)據(jù)
① 在 v-bind: 指令之前添加 v-model 指令
② 在子組件中聲明 emits 自定義事件,格式為 update:xxx
③ 調(diào)用 $emit() 觸發(fā)自定義事件,更新父組件中的數(shù)據(jù)
案例:
// App.vue
<template>
<div>
<h1>App 根組件 ---- {{count}}</h1>
<button @click="count += 1">+1</button>
<hr />
<my-counter v-model:number="count"></my-counter>
</div>
</template>
// Counter.vue
<template>
<div>
<p>count值是:{{number}}</p>
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
name: 'MyCounter',
props: ['number'],
emits: ['update:number'],
methods: {
add() {
this.$emit('update:number', this.number + 1)
}
}
}
</script>
效果:
子父組件中數(shù)據(jù)同步
總結(jié):
① 能夠知道如何對(duì) props 進(jìn)行驗(yàn)證
數(shù)組格式、對(duì)象格式
type、default、required、validator
② 能夠知道如何使用計(jì)算屬性
computed 節(jié)點(diǎn)、必須 return 一個(gè)結(jié)果、緩存計(jì)算結(jié)果
③ 能夠知道如何為組件綁定自定義事件
v-on 綁定自定義事件、emits、$emit()
④ 能夠知道如何在組件上使用 v-model
應(yīng)用場(chǎng)景:實(shí)現(xiàn)組件內(nèi)外的數(shù)據(jù)同步文章來源:http://www.zghlxwxcb.cn/news/detail-458922.html
v-model:props名稱、emits、$emit(‘update:props名稱’)文章來源地址http://www.zghlxwxcb.cn/news/detail-458922.html
到了這里,關(guān)于Vue3:組件基礎(chǔ)(下)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!