组件接受的选项大部分与Vue实例一样,而选项props是组件中非常重要的一个选项。在 Vue 中,父子组件的关系可以总结为 props down, events up。父组件通过 props 向下传递数据给子组件,子组件通过 events 给父组件发送消息。本文将详细介绍Vue组件选项props
静态props
组件实例的作用域是孤立的。这意味着不能 (也不应该) 在子组件的模板内直接引用父组件的数据。要让子组件使用父组件的数据,需要通过子组件的 props 选项
使用Prop传递数据包括静态和动态两种形式,下面先介绍静态props
子组件要显式地用 props 选项声明它期待获得的数据
var childNode = { template: '<div>{{message}}</div>', props:['message'] }
静态Prop通过为子组件在父组件中的占位符添加特性的方式来达到传值的目的
<div> <parent></parent> </div> <script> var childNode = { template: '<div>{{message}}</div>', props:['message'] } var parentNode = { template: ` <div> <child message="aaa"></child> <child message="bbb"></child> </div>`, components: { 'child': childNode } }; // 创建根实例 new Vue({ el: '#example', components: { 'parent': parentNode } }) </script>
命名约定
对于props声明的属性来说,在父级HTML模板中,属性名需要使用中划线写法
var parentNode = { template: ` <div> <child my-message="aaa"></child> <child my-message="bbb"></child> </div>`, components: { 'child': childNode } };
子级props属性声明时,使用小驼峰或者中划线写法都可以;而子级模板使用从父级传来的变量时,需要使用对应的小驼峰写法
var childNode = { template: '<div>{{myMessage}}</div>', props:['myMessage'] } var childNode = { template: '<div>{{myMessage}}</div>', props:['my-message'] }
动态props
在模板中,要动态地绑定父组件的数据到子模板的 props,与绑定到任何普通的HTML特性相类似,就是用 v-bind。每当父组件的数据变化时,该变化也会传导给子组件
var childNode = { template: '<div>{{myMessage}}</div>', props:['myMessage'] } var parentNode = { template: ` <div> <child :my-message="data1"></child> <child :my-message="data2"></child> </div>`, components: { 'child': childNode }, data(){ return { 'data1':'aaa', 'data2':'bbb' } } };
传递数字
初学者常犯的一个错误是使用字面量语法传递数值
<!-- 传递了一个字符串 "1" --> <comp some-prop="1"></comp> <div> <my-parent></my-parent> </div> <script> var childNode = { template: '<div>{{myMessage}}的类型是{{type}}</div>', props:['myMessage'], computed:{ type(){ return typeof this.myMessage } } } var parentNode = { template: ` <div> <my-child my-message="1"></my-child> </div>`, components: { 'myChild': childNode } }; // 创建根实例 new Vue({ el: '#example', components: { 'MyParent': parentNode } }) </script>
因为它是一个字面 prop,它的值是字符串 "1" 而不是 number。如果想传递一个实际的 number,需要使用 v-bind,从而让它的值被当作JS表达式计算
<!-- 传递实际的 number --> <comp v-bind:some-prop="1"></comp> var parentNode = { template: ` <div> <my-child :my-message="1"></my-child> </div>`, components: { 'myChild': childNode } };
或者可以使用动态props,在data属性中设置对应的数字1
var parentNode = { template: ` <div> <my-child :my-message="data"></my-child> </div>`, components: { 'myChild': childNode }, data(){ return { 'data': 1 } } };
props验证
可以为组件的 props 指定验证规格。如果传入的数据不符合规格,Vue会发出警告。当组件给其他人使用时,这很有用
要指定验证规格,需要用对象的形式,而不能用字符串数组