一、props 验证
1. 对象类型的 props 节点
使用对象类型的 props 节点,可以对每个 prop 进行数据类型的校验。
使用数组类型的 props 节点的缺点:无法为每个 prop 指定具体的数据类型。
2. props 验证方案
2.1 基础类型检查
直接为组件的 prop 属性指定基础的校验类型。
2.2 多个可能的类型
通过数组指定多个可能的类型
export default{
props:{
propA:[String,Number],//propA属性的值可以是字符串或数字
},
}
2.3 必填项校验
如果组件的某个 prop 属性是必填项,必须有传递属性的值。
export default{
props:{
propB:{
type:String, //当前属性值必须是String类型
required:true //当前属性值是必填项
}
}
}
2.4 属性默认值
export default{
props: {
propC: {
type: Number,
default:100
}
}
}
2.5 自定义验证函数
export default{
props:{
propD:{
validator(value){
//propD属性的值必须匹配下列字符串中的一个
//validator函数返回值为true表示验证通过,false表示验证失败
return ['success', 'warning','danger'].indexOf(value) !== -1
}
}
}
}
二、计算属性
1. 什么是计算属性
本质是一个 function 函数,可以实时监听 data 中数据的变化,并 return 一个计算后的新值,供组件渲染 DOM 时使用
2. 如何声明计算属性
以 function 函数的形式声明到组件的 computed 中。
注意:计算属性中必须有 return 值!
<template>
<div>
<input type="text" v-model.number="count" />
<p>{{ count }} 乘以 2 的值为:{{ plus }}</p>
</div>
</template>
<script>
export default {
name: 'MyCounter',
data() {
return {count: 1}
},
computed: {
plus() {
return this.count * 2
},
},
}
</script>
3. 使用注意
- 计算属性必须定义在 computed 节点中
- 计算属性必须是一个 function 函数
- 计算属性必须有返回值
- 计算属性必须当做普通属性使用
4. 计算属性 vs 方法
计算属性会缓存计算的结果,只有计算属性的依赖项发生变化时,才会重新进行运算,性能好。
方法的计算结果无法被缓存,性能低。
computed: {
plus() {
console.log('计算属性被执行了')
return this.count * 2
},
},
methods: {
plus() {
console.log('方法被执行了')
return this.count * 2
}
}
三、自定义事件
1. 什么是自定义事件
让组件的使用者可以监听到组件内状态的变化
2. 自定义事件的 3 个使用步骤
在封装组件时:
- 声明自定义事件
- 触发自定义事件
在使用组件时:
- 监听自定义事件
<template>
<div>
<p>count 的值是:{{ count }}</p>
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
name: 'MyCounter',
// 1. 声明自定义事件
emits: ['countChange'],
data() {
return {
count: 0,
}
},
methods: {
add() {
this.count++
// 2. this.$emit() 触发自定义事件
this.$emit('countChange', this.count)
},
},
}
</script>
- 自定义事件必须事先在 emits 节点中声明。
- 在 emits 节点下声明的自定义事件,通过 this.$emit('自定义事件的名称') 方法触发。
- 在使用自定义的组件时,通过 v-on 的形式监听自定义事件。
-
在调用 this.$emit() 方法触发自定义事件时,通过第 2 个参数为自定义事件传参。
四、组件上的 v-model
1. 为什么需要在组件上使用 v-model
v-model 是双向数据绑定指令,当需要维护组件内外数据的同步时,可以在组件上使用 v-model
- 外界数据的变化会自动同步到 counter 组件中
- counter 组件中数据的变化,也会自动同步到外界
2. 在组件上使用 v-model 的步骤
① 父组件通过 v-bind: 属性绑定的形式,把数据传递给子组件
② 子组件中,通过 props 接收父组件传递过来的数据
① 在 v-bind: 指令之前添加 v-model 指令
② 在子组件中声明 emits 自定义事件,格式为 update:xxx
③ 调用 $emit() 触发自定义事件,更新父组件中的数据
<template>
<div>
<!--active控制按钮的样式变化,通过activeBtnIndex决定状态-->
<todo-button v-model:active="activeBtnIndex"></todo-button>
</div>
</template>
<script>
// 导入 TodoButton 组件
import TodoButton from './components/todo-button/TodoButton.vue'
export default{
name: 'MyApp',
data() {
return {
activeBtnIndex: 0,
}
},
computed: {
tasklist() {
switch(this.activeBtnIndex) {
case 0:
return this.todolist
case 1:
return this.todolist.filter(x => x.done === true)
case 2:
return this.todolist.filter(x => x.done !== true)
}
}
},
},
</script>