能让组件如同我们所知的js函数一样,在被使用时能够接收参数,并根据参数有不同的展现
①给组件添加props选项
在自定义组件的内容配置对象里面给上一个props选项,他和template同级,如下:
Vue.component('props-message',{
props:['message'],
template:`{{message}}`
})
②在调用组件时传入实际参数即可
在调用组件的标签上,按照标签属性的写法即可传入参数到组件中
注意:传递的参数名称(属性名)应该包含在组件的props选项中的数组或者对象中,否则组件无法接收你的值
<div id="app">
<props-message message='测试数据'>props-message>
div>
③完整代码及效果
对于props中的参数,我们可以如同data里面的数据一样访问
<div id="app">
<props-message message='测试数据'>props-message>
div>
<script>
Vue.component('props-message', {
props: ['message'],
template: `这是一个自定义组件,父组件传给我的内容是:{{message}}`
})
var vueApp = new Vue({
el: '#app',
})
script>
①传参时名称格式的问题
由于html不区分大小写,当使用DOM网页模板时,写在props数组或对象中的参数名为驼峰命名时,在参数传递时应该用分隔符将组成驼峰的单词进行分开
比如在props中有驼峰命名参数myName, 那么在传参时就应该写成my-Name或者my-name(由于html不区分大小写,所以my-name==my-Name,但是最标准写法应该是全小写中杠线分割)
<div id="app">
<props-message my-Message='测试数据'>props-message>
div>
<script>
Vue.component('props-message', {
props: ['myMessage'],
template: `这是一个自定义组件,父组件传给我的内容是:{{myMessage}}`
})
var vueApp = new Vue({
el: '#app',
})
script>
当然,如果是使用的template模板字符串,可以忽略此限制
②传递动态数据
v-bind绑定属性值的一个特性:一般情况下,使用v-bind给元素特性(attribute)传递值时,Vue会将" "中的内容当做一个表达式,比如:
<div my-Message='message'>div>
上面这样,div元素的my-Message特性值就是message
而这样
<div v-bind:my-Message='message'>div>
这里的message应该是Vue实例的data的一个属性,这样div元素的my-Message特性值就是message这个属性的值
之所以说是一般情况,是因为class和style特性并不是这样。用v-bind:class和class传入正常的类名,效果是一样的,因为对于这两个特性,Vue采用了合并而不是替换的原则
之后,这时我们就可以使用v-bind绑定要传递的参数,如下:
注意: 如果你传参时没有使用v-bind指令绑定,那么不管你的参数是什么类型,子组件接收到的都是字符串,哪怕你写数组对象也是如此
③Vue2参数传递是单向数据流
3.由于在js中,对象和数组是引用类型,指向同一个内存空间,所以当我们通过v-bind绑定的参数是一个数组或对象,然后传递过来时,那么他们在子组件的改变会影响到父组件的(这和vue组件无关,由js特性所决定的,如果想避免这种情况,那么在子组件接收到此引用类型参数后处理下即可,如用JSON方法处理或用Object.assign()方法处理等)
演示代码:
<div id="app">
<h3>{{message.str}}h3>
<props-message v-bind:my-Message='message'>props-message>
div>
<script>
Vue.component('props-message', {
props: ['myMessage'],
template: `这是一个自定义组件,传给我的内容是:{{myMessage.str}}
`,
methods: {
fn: function () {
this.myMessage.str = '我被修改了';
}
}
})
var vueApp = new Vue({
el: '#app',
data: {
message: {
str: '测试数据'
}
}
})
script>
①参数原封不动的使用
直接调用,不做任何处理
Vue.component('props-message', {
props: ['myMessage'],
template: `这是一个自定义组件,传给我的内容是:{{myMessage}}`,
});
②参数作为某种状态的初始值使用
直接在子组件的data选项中声明一个字段来接收此参数,然后我们只需要操作这个字段就可以了,从而可以避免直接操作参数属性,如:
<div id="app">
<person-message :num='num'>person-message>
div>
<script>
Vue.component('person-message', {
props: ['num'],
template: `
vip积分:{{sonNum}}
`,
data: function () {
return {
sonNum: this.num,
}
},
methods: {
fn: function () {
this.sonNum++;
console.log(this.userInfo.age)
}
},
})
var vueApp = new Vue({
el: '#app',
data: {
num: 100,
}
})
script>
效果图:初始积分是100
注意:
此时由于值中转了下,然后也不是引用类型,所以在这里我们父组件对此参数修改了,子组件就不会同步更改【即上面的sonNum参数变了,但是参数赋值的num不会变】
如果要实现同步更改,那么我们可以通过侦听属性选项实现,如下:
<script>
Vue.component('person-message', {
props: ['num'],
template: `
vip积分:{{sonNum}}
`,
data: function () {
return {
sonNum: this.num,
}
},
methods: {
fn: function () {
this.sonNum++;
}
},
watch: {
sonNum:function(oldV,newV){
this.num = newV
console.log(this.num);
}
}
})
var vueApp = new Vue({
el: '#app',
data: {
num: 100,
}
})
</script>
③参数作为需要被转换的原始值使用
这种情况我们需要使用计算属性,比较好统一管理
<div id="app">
<person-message :num='num' :user-info="user">person-message>
div>
<script>
Vue.component('person-message', {
props: ['num','userInfo'],
template: `
vip积分:{{sonNum}}
用户信息:{{userData}}
`,
data: function () {
return {
sonNum: this.num,
}
},
methods: {
fn: function () {
this.sonNum++;
console.log(this.userInfo.age)
}
},
computed: {
userData:function(){
let str = "【姓名:"+this.userInfo.name+",性别:"+this.userInfo.sex+",年龄:"+this.userInfo.age+"】"
return str;
}
}
})
var vueApp = new Vue({
el: '#app',
data: {
num: 100,
user:{name:'zs',sex:'nan',age:18},
}
})
script>
自动的对传入参数进行检验,那么我们就需要让props的值为一个对象
进行参数检验的必要性:如果我们的组件给别人使用时,我们没在组件中进行参数验证,那么当接收到一些毁灭性参数值或类型我们组件基本上就废了
①使用对象形式的props验证参数的基本方式
使用对象接收参数时,参数后面必须要跟上其类型,否则会出异常
如果验证不通过,引用开发版本的vue.js时,会在控制台抛出警告
注意:
<div id="app">
<my-component :person-prop='person'>my-component>
div>
<script>
// 自定义Person构造器
function Person(name, age) {
this.name = name
this.age = age
}
Vue.component('my-component', {
template: `名字: {{ personProp.name }}, 年龄: {{ personProp.age }} `,
props: {
personProp: {
type: Person // 指定类型
}
}
})
new Vue({
el: '#app',
data: {
person: new Person(2, 3) // 传入Number类型会报错
}
})
script>
props: {
age: [Number, String], //验证number必须为数字或者字符串
sex: String, //验证必须是字符串
vip: Boolean, //验证必须是布尔类型
teg: Array, //验证必须是数组
name: Object, //验证必须是对象
fn: Function, //验证必须是对象
},
③在验证参数时允许给定默认值
如果有参数传入那么就会覆盖掉默认参数
④对象和数组参数默认值需要用一个函数来返回
⑤在验证参数时可以要求某些参数必传
sex: {
type: String,
required:true,
},
原文:https://blog.csdn.net/weixin_41350225/article/details/89160007