前面我们实现了通过组件把模板内容进行复用,这是不错的事情,但是我们却不希望在任何地方任何时候组件都是都是那样的一层不变。
我们更希望在不同的情况下,组件有不同的展现,这样它才是有趣的,更让我们喜欢的。
而要实现这个需要,就需要使用props了,他能让组件如同我们所知的js函数一样,在被使用时能够接收参数,并根据参数有不同的展现。
要通过props来实现让组件如同js函数样接收参数,并根据参数有不同的展现。我们进行一下几个步骤。
1.给组件添加props选项
在自定义组件的内容配置对象里面给上一个props选项,他和template同级。如下:
Vue.component("person-message", {
props:["name","sex"],
template: `用户信息
姓名:{{name}},性别:{{sex}}`,
});
注意
1.这个props选项的值为一个对象或者数组,有点类似于js函数的形参,规定了这个组件能够接收那些参数。
2.然后这里要注意下:对于组件传参采取的是对象传参,即传入的参数的名称要和props里面给定的名称一致,否则无法接收到任何参数。
2.在调用组件时传入实际参数即可
你在调用组件的标签上,按照标签属性的写法即可传入参数到组件中。
当然,就和上面所说一样,我们传递的参数名称(属性名)应该包含在组件的props选项中的数组或者对象中。否则组件无法接收你的值。
4.使用props传递分析
1.对象传参就不多说了
2.我们写在props中的字段名,可以和调用data返回的中的数据形式一样,直接写名字进行调用。不过一个是来自父级,一个是来自本身。
3.对于传递参数的数量没有限制,这意味着你可以传递任意个数的参数,只要写在props里面就可以了
4.对于props参数,在使用时,我们在dev-tools中是无法修改其值的。
5.当props中的字段和data中的中的字段不允许相同,否则会直接报错
1.传参时,名称格式的问题
由于html不区分大小写,当使用DOM网页模板时,写在props数组或对象中的参数名为驼峰命名时,在参数传递时应该用分隔符将组成驼峰的单词进行分开。
比如在props中有驼峰命名参数myName, 那么在传参时就应该写成my-Name,或者,my-name(由于html不区分大小写,所以my-name==my-Name)
当然,如果是使用的template模板字符串,可以忽略此限制。
2.有时我们需要传递动态数据
所谓动态数据就是说,数据A从父组件传递到子组件后,如果在父组件A发生了变化,那么子组件中接收到的参数A也要同步发生变化。【即父变了子就要变】
这时我们就可以使用v-bind绑定要传递的参数,如下
注意: 如果你传参时没有使用v-bind指令绑定,那么不管你的参数是什么类型,子组件接收到的都是字符串,哪怕你写数组对象也是如此。、
3.Vue2参数传递是单向数据流
对于现在盛行的vue2来说,通过props传递参数是单向的:
1.即只允许父组件传递参数到子组件,而不允许子组件传递到父组件。
2.在父组件参数值变了子组件也会变,但是子组件参数值变了父组件却不会变,而且在子组件去修改参数的话会被vue警告:
大致含义:
避免直接对prop进行改变,因为每当父组件重新呈现时,都会覆盖该值。相反,使用基于PROP值的数据或计算属性是不错的选择。
3.由于在js中,对象和数组是引用类型,指向同一个内存空间,所以当我们通过v-bind绑定的参数是一个数组或对象,然后传递过来时,那么他们在子组件的改变会影响到父组件的。
(这和vue组件无关,由js特性所决定的,如果想避免这种情况,那么在子组件接收到此引用类型参数后处理下即可,如用JSON方法处理或用Object.assign()方法处理等)
提示:
1.vue1的时候可以对参数进行双向绑定,子组件变了,父组件也能变。不过这加强了父子组件的耦合度,子组件也许无意间就会修改到父组件,所以被抛弃了。。。
2.React和vue一样也是单向数据流,默认情况下只允许父到子,不允许子到父。
大致有三种使用情况
1)参数原封不动的使用
这种情况,直接调用,不做任何处理
2)参数作为某种状态的初始值使用
那么你的做法应该是:
直接在子组件的data选项中声明一个字段来接收此参数,
然后我们只需要操作这个字段就可以了,从而可以避免直接操作参数属性,如:
注意:此时由于值中转了下,然后也不是引用类型,所以在这里我们父组件对此参数修改了,子组件就不会同步更改【如上initCount参数会变,但是参数赋值的count不会变】
如果要实现同步更改,那么我们可以通过监听器选项实现,如下:
3)参数作为需要被转换的原始值使用
概述
前面我们说了,props选项的值为一个对象或者数组,而前面我们主要使用的数组形式,这没问题。
但是有时候我们要使用vue内置的优秀功能,比如自动的对传入参数进行检验,那么我们就需要让props的值为一个对象了。
进行参数检验的必要性:
不管是我们的组件给别人使用,还是别人的组件给我们使用,都需要组件参数验证功能的。
如果我们的组件给别人使用时,我们没在组件中进行参数验证,那么当接收到一些毁灭性参数值或类型我们组件基本上就废了。
【比如当用户的参数为某个值或者某种类型时我们的组件才会正常运行,但是我在组件中又是直接使用的,没做容错处理,那么当用户不传入符合我们预期的值时,或者根本就没有传参时,这时我们的组件就直接over了】
1)使用对象形式的props验证参数的基本方式
如果验证不通过,引用开发版本的vue.js时,会在控制台抛出警告:
注意:
1.如果你参数的类型是一个函数,那么你可以显示的给出type:Functin,然后数作为函数的情况,使用时应该给上括号,以调用此函数。
2.如果你参数的类型为你自定义的一个类型,比如是你定义的某个函数或对象,那么你也可以给出 type:自定义类型名来进行验证
2)在验证参数时允许为几种类型之一
props: {
age: [Number, String], //验证number必须为数字或者字符串
sex: String, //验证必须是字符串
vip: Boolean, //验证必须是布尔类型
teg: Array, //验证必须是数组
name: Object, //验证必须是对象
},
3)在验证参数时允许给定默认值
这和函数的默认参数类似,当没有参数传入时就会使用默认值
效果:
如果有参数传入那么就会覆盖掉默认参数
4)对象和数组参数默认值需要用一个函数来返回
如果不使用函数,会有警告如下:
5)在验证参数时可以要求某些参数必传
sex: {
type: String,
required:true,
},