Vue Prop使用
组件实例的作用域是孤立的。这意味着不能 (也不应该) 在子组件的模板内直接引用父组件的数据。要让子组件使用父组件的数据,我们需要通过子组件的 props 选项。vue 实例Vue.component('child', {props: ['message'],tem
·
组件实例的作用域是孤立的。这意味着不能 (也不应该) 在子组件的模板内直接引用父组件的数据。要让子组件使用父组件的数据,我们需要通过子组件的 props 选项。
<html>
<head>
<title>vue 实例</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<child :message="parentMessage"></child>
</div>
<script>
Vue.component('child', {
props: ['message'],
template: '<span>{{ message }}</span>'
})
new Vue({
el: '#app',
data: {
parentMessage: 'vue prop'
}
})
</script>
</body>
</html>
1、字面量语法 vs 动态语法
初学者常犯的一个错误是使用字面量语法传递数值:
<!-- 传递了一个字符串 "1" -->
<comp some-prop="1"></comp>
因为它是一个字面 prop,它的值是字符串 "1" 而不是 number。如果想传递一个实际的 number,需要使用 v-bind,从而让它的值被当作 JavaScript 表达式计算:
<!-- 传递实际的 number -->
<comp v-bind:some-prop="1"></comp>
prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解。另外,每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着你不应该在子组件内部改变 prop。如果你这么做了,Vue 会在控制台给出警告。
为什么我们会有修改 prop 中数据的冲动呢?通常是这两种原因:
(1)、prop 作为初始值传入后,子组件想把它当作局部数据来用;
(2)、prop 作为初始值传入,由子组件处理成其它数据输出。
对这两种原因,正确的应对方式是:
A、定义一个局部变量,并用 prop 的值初始化它:
props: ['initialCounter'],
data: function () {
return { counter: this.initialCounter }
}
B、定义一个计算属性,处理 prop 的值并返回。
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
注意在 JavaScript 中对象和数组是引用类型,指向同一个内存空间,如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态。
3、Prop 验证
我们可以为组件的 props 指定验证规格。如果传入的数据不符合规格,Vue 会发出警告。当组件给其他人使用时,这很有用。
要指定验证规格,需要用对象的形式,而不能用字符串数组:
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 会在抛出警告 (如果使用的是开发版本)。注意 props 会在组件实例创建之前进行校验,所以在 default 或 validator 函数里,诸如 data、computed 或 methods 等实例属性还无法使用。
4、非 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 的根元素上
<input type="date" class="form-control" data-3d-date-picker="true">
5、替换/覆盖现有的特性
想象一下这是 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>
在这个 case 当中,我们定义了两个不一样的 class 的值:
(1)、form-control,来自组件的模板
(2)、date-picker-theme-dark,从父组件传进来的
对于多数特性来说,传递给组件的值会覆盖组件本身设定的值。即例如传递 type="large" 将会覆盖 type="date" 且有可能破坏该组件!索性我们对待 class 和 style 特性会更聪明一些,这两个特性的值都会做合并 (merge) 操作,让最终生成的值为:form-control date-picker-theme-dark。
<input type="date" class="form-control date-picker-theme-dark" data-3d-date-picker="true">
更多推荐
已为社区贡献8条内容
所有评论(0)