组件的属性也就是组件的标签,使用props(property的简写)来完成组件属性的声明。
props是外部给组件传入的数据。data是组件内部的数据。
须知:属性可以多传 但是注册了的属性就必须传 不然有可能会在使用时因为取值问题出BUG。
用途:用于组件之间的传值,正常情况下被导入的那个组件内想使用导入它的那个组件的data数据值是不能实现的,这里的组件的属性可以办到。在其它组件中使用该组件时用到的对应的属性设置的值会传给该组件。
一:使用Prop传递静态数据
1)、在组件内部增加配置项props来声明组件里的属性。
props里面可以声明多个属性,是个数组:
let myContext= {
props:["name","sex"], //声明了两个自定义属性
template:`<div>
<p>{{msg}}</p>
<p>信息:</p>
<p>姓名:{{name}}</p>
<p>性别:{{sex}}</p>
</div>`,
data:function(){
return {
msg:"欢迎来到王者荣耀!"
}
}
};
2)、使用组件时,给组件传入数据:
<!-- 使用组件时,给属性传入值,传入的值,就可以在组件内部使用 -->
<my-context name="娜可露露" sex="nv"></my-context>
我们把封装组件和封装函数放到一起看一下, 在组件内部用props声明的属性,相当于
封装函数时声明的形参。使用组件时,相当于调用函数,传递实参。
props是外部给组件传入的数据(相当于函数中的参数)。
data是组件内部的数据(相当于函数里的局部变量)。
二:使用Prop传递动态数据
组件属性和官方标签的属性是同样的道理。
所以,给组件的属性也可以v-bind 数据。即:绑定动态的数据。
<my-com-parent v-bind:name="name" sex="男"></my-com-parent>
<!-- name为变量 -->
如果你想把一个对象的所有属性作为组件的prop 进行传递,可以使用不带任何参数的 v-bind属性(用v-bind而不是v-bind:prop-name)。例如:
todo: {
text: 'Learn Vue',
isComplete: false
}
<todo-item v-bind="todo"></todo-item>
等价于:
<todo-item
v-bind:text="todo.text"
v-bind:is-complete="todo.isComplete"
></todo-item>
透传属性:如果说在自定义标签里写的自定义属性,没有用props声明,那么,vue会默认把属性继承给根标签。所以,在在定义属性里写的class和style是可以起作用。
在子组件里,通过
this.$attrs
可以拿到透传的属性(除了官方的属性,如:style,class,id等)注意:在 JavaScript 中对象和数组是通过引用传入的(传的是地址),所以对于一个数组或对象类型的 prop 来说,在子组件中改变这个对象或数组本身将会影响到父组件的状态(data),相当于函数的形参是引用类型,这个是不建议的。
三:Prop(类型)验证
vueJS还提供了对属性类型的验证、属性默认值,是否必须等等。这时候,props不能使用数组,而需要使用对象。
如:
props:{
"name":{
type:String, //限制name属性的类型是字符串
required:true //限制name属性是必须传入值的。
},
"sex":[String,Number], //限制sex属性的值可以为字符串,也可以为数字
"age":{
type:Number, //限制age属性的类型是数字型
default:10 // age属性的默认值是10 。如果没有给age传值,那么age就是10。
},
"isadult":Boolean
},
四:单向数据流
父组件可以给子组件传递数据。反之不行。
Prop 是单向绑定的:当父组件的属性(数据)变化时,将传导给子组件,但是反过来不会。这是为了防止子组件无意间修改了父组件的状态,来避免应用的数据流变得难以理解。
另外,每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着你不应该在子组件内部改变 prop。如果你这么做了,Vue 会在控制台给出警告。
总结:组件就是标签,prop是标签的属性
prop是外部传入的数据,data是组件内部的数据