#单向数据流
Prop是单向绑定的:当父组件的属性变化时将传导给子组件,但是反过来不会,这是为了防止子组件无意间修改了父组件的状态,来避免应用的数据流变得难以理解。
另外,每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着你不应该在子组件内部改变 prop。如果你这么做了,Vue 会在控制台给出警告。
在两种情况下我们很容易忍不住想去修改prop中的数据:
1.Prop作为初值传入后,子组件想把他当做局部数据来使用。‘
2.Prop作为原始数据传入,由子组件处理成其他数据输出。
对这两种情况,正确的应对方式是:
1.定义一个局部变量,并用prop的值初始化它。
props: ['initialCounter'],
data: function () {
return { counter: this.initialCounter }
}
2.定义一个计算属性,处理prop的值并且返回:
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
注意在 JavaScript 中对象和数组是引用类型,指向同一个内存空间,如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态。
#prop验证:
我们可以为组件的prop指定验证规则。如果传入的数据不符合要求,Vue 会发出警告。这对于开发给他人使用的组件非常有用。
需要指定验证规则,需要用对象的形式来定义prop,而不能用字符串数组:
Vue.component('example', {
props: {
// 基础类型检测 (`null` 指允许任何类型)
propA: Number,
// 可能是多种类型
propB: [String, Number],
// 必传且是字符串
propC: {
type: String,
required: true
},
// 数值且有默认值
propD: {
type: Number,
default: 100
},
// 数组/对象的默认值应当由一个工厂函数返回
propE: {
type: Object,
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
return value > 10
}
}
}
})
type可以是下面原生构造器:
- String
- Number
- Boolean
- Function
- Object
- Array
- Symbol
type
也可以是一个自定义构造器函数,使用
instanceof
检测。
当 prop 验证失败,Vue 会抛出警告 (如果使用的是开发版本)。注意 prop 会在组件实例创建之前进行校验,所以在 default
或 validator
函数里,诸如 data
、computed
或 methods
等实例属性还无法使用。
非Prop特性:
所谓非Prop特性,就是指它可以直接传入组件,而不需要定义相应的prop。
尽管为组件定义明确的 prop 是推荐的传参方式,组件的作者却并不总能预见到组件被使用的场景。所以,组件可以接收任意传入的特性,这些特性都会被添加到组件的根元素上。
例如,假设我们使用了第三方组件 bs-date-input
,它包含一个 Bootstrap 插件,该插件需要在 input
上添加 data-3d-date-picker
这个特性。这时可以把特性直接添加到组件上 (不需要事先定义 prop
):
<bs-date-input data-3d-date-picker="true"></bs-date-input> |
添加属性 data-3d-date-picker="true"
之后,它会被自动添加到 bs-date-input
的根元素上。
#替换合并现有特性
假设这是 bs-date-input
的模板:
<input type="date" class="form-control">
为了给该日期选择器插件增加一个特殊的主题,我们可能需要增加一个特殊的 class,比如:
<bs-date-input
data-3d-date-picker="true"
class="date-picker-theme-dark"
></bs-date-input>
在这个例子当中,我们定义了两个不同的 class
值:
form-control
,来自组件自身的模板date-picker-theme-dark
,来自父组件
type="large"
将会覆盖
type="date"
且有可能破坏该组件!所幸我们对待
class
和
style
特性会更聪明一些,这两个特性的值都会做合并 (merge) 操作,让最终生成的值为:
form-control date-picker-theme-dark
。