1、父组件向子组件传递数据
在组件中,使用选项props来声明需要从父级接收到的数据。
props的值有两种方式:
方式一:字符串数组,数组中的字符串就是传递时的名称。
方式二:对象,对象可以设置传递时的类型,也可以设置默认值等。
1、 props传字符串数组
props: ['cmovies', 'cmessage']
<div id="app">
<div>
<cpn v-bind:cmovies="movies" :cmessage="message"></cpn>
</div>
</div>
<template id="cpn">
<div>
<ul>
<li v-for="items in cmovies">{{items}}</li>
</ul>
<h2>{{cmessage}}</h2>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
//父传子:props
const cpn = {
template: '#cpn',
//这样数组的写法定义也可以
props: ['cmovies', 'cmessage']
};
const app = new Vue({
el: '#app',
data: {
message: 'hello',
movies: ['111', '222', '333', '444']
},
components: {
cpn
}
})
</script>
2、 props传对象
1、类型限制
props: { //1、类型限制 //指定cmovies必须是数组类型 cmovies: Array, //指定cmessage必须是String类型 cmessage: String };
2、提供一些默认值以及必传值
require为true的意思是别人用cpn这个组件的时候,必须传cmessage这个数据<cpn :cmessage="message"></cpn>,不传就报错
required: trueprops: { //2、提供一些默认值以及必传值 cmessage: { //指定cmessage必须是String类型 type: String, //指定cmessage的默认值 default: '默认值', //require为true的意思是别人用cpn这个组件的时候,必须传cmessage这个数据<cpn :cmessage="message"></cpn>,不传就报错 required: true } };
当类型是对象或者数组时,默认值必须是一个函数
cmovies: { type: Array, //default: ['默认值']//vue2.5.2以下可以 //但是2.5.17以上会报错这是因为当类型是对象或者数组时,默认值必须是一个函数 default() { return ['默认值']; } //validator可以自己做验证 }
数据验证都支持那些数据类型:
还可以自定义验证函数
传对象的几种形式:
具体例子如下:
<div id="app">
<div>
<cpn v-bind:cmovies="movies" :cmessage="message"></cpn>
</div>
</div>
<template id="cpn">
<div>
<ul>
<li v-for="items in cmovies">{{items}}</li>
</ul>
<h2>{{cmessage}}</h2>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
//父传子:props
const cpn = {
template: '#cpn',
//props: ['cmovies', 'cmessage'],这样数组的写法定义也可以
props: {
//2、提供一些默认值以及必传值
cmessage: {
//指定cmessage必须是String类型
type: String,
//指定cmessage的默认值
default: '默认值',
//require为true的意思是别人用cpn这个组件的时候,必须传cmessage这个数据<cpn :cmessage="message"></cpn>,不传就报错
required: true
},
cmovies: {
type: Array,
//default: ['默认值']//vue2.5.2以下可以
//但是2.5.17以上会报错这是因为当类型是对象或者数组时,默认值必须是一个函数
default() {
return ['默认值'];
}
//validator可以自己做验证
}
}
};
const app = new Vue({
el: '#app',
data: {
message: 'hello',
movies: ['111', '222', '333', '444']
},
components: {
cpn
}
})
</script>
3、props中的驼峰标识
v-bind不支持驼峰,所以不要写cInfo,如果非要写cInfo,那绑定的时候用:c-info="info"不是:cInfo="info",如下面的childMyMessage
<div id="app">
<cpn :cinfo="info" :child-my-message="message"></cpn>
</div>
<!-- 定义子组件模板的时候最外层必须有一个根,所以必须要用div包起来-->
<template id="cpn">
<div>
<ul>
<li v-for="(value,key,index) in cinfo">{{value}}-{{key}}-{{index}}</li>
</ul>
<p>{{childMyMessage}}</p>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const cpn = {
template: '#cpn',
props: {
//注意 v-bind不支持驼峰,所以不要写cInfo,如果非要写cInfo,那绑定的时候用:c-info="info"不是:cInfo="info",,如下面的childMyMessage
cinfo: {
typeof: Object,
default() {
return {};
}
},
childMyMessage: {
typeof: String,
default() {
return "default;"
}
}
}
}
const app = new Vue({
el: '#app',
data: {
info: {
name: 'Doe',
age: 19,
height: 1.65
},
message: 'hello'
},
components: {
cpn
}
})
</script>
2、子组件向父组件传递数据
这个时候,我们需要使用自定义事件来完成。
自定义事件的流程
1、在子组件中,通过$emit()来触发事件。
$emit发射一个事件,事件的名称叫itemClick,发射事件的同时传递一个参数item。这个时候父组件需要监听这个事件
this.$emit('itemclick', item)<!--子组件模板--> <template id="cpn"> <div> <button v-for="item in categories" @click="itemclick(item)">{{item.name}}</button> </div> </template> <script> //子组件 const cpn = { template: '#cpn', data() { return { categories: [ { id: 'aaa', name: '热门推荐' }, { id: 'bbb', name: '手机数码' }, { id: 'ccc', name: '家用家电' }, { id: 'ddd', name: '电脑办公' } ] } }, methods: { itemclick(item) { //要把点击了谁传递给父组件 //1、$emit发射一个事件,事件的名称叫itemClick,发射事件的同时传递一个参数item。这个时候父组件需要监听这个事件 this.$emit('itemclick', item) } } } </script>
2、在父组件中,通过v-on来监听子组件事件
<!--
v-on:itemClick用来监听子组件发射的itemClick事件
因为这个事件不是浏览器的事件,所以不加括号不会传event,传的是发射事件的参数item
-->
<cpn @itemclick="cpnclick"></cpn>
<!--父组件模板--> <div id="app"> <!-- 2、v-on:itemClick用来监听子组件发射的itemClick事件 因为这个事件不是浏览器的事件,所以不加括号不会传event,传的是发射事件的参数item --> <cpn @itemclick="cpnclick"></cpn> </div> <script> //父组件 const app = new Vue({ el: '#app', data: { message: 'hello' }, components: { cpn }, methods: { cpnclick(item) { console.log(item) } } }) </script>
总代码
<body>
<!--父组件模板-->
<div id="app">
<!--
2、v-on:itemClick用来监听子组件发射的itemClick事件
因为这个事件不是浏览器的事件,所以不加括号不会传event,传的是发射事件的参数item
-->
<cpn @itemclick="cpnclick"></cpn>
</div>
<!--子组件模板-->
<template id="cpn">
<div>
<button v-for="item in categories" @click="itemclick(item)">{{item.name}}</button>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
//子组件
const cpn = {
template: '#cpn',
data() {
return {
categories: [
{ id: 'aaa', name: '热门推荐' },
{ id: 'bbb', name: '手机数码' },
{ id: 'ccc', name: '家用家电' },
{ id: 'ddd', name: '电脑办公' }
]
}
},
methods: {
itemclick(item) {
//要把点击了谁传递给父组件
//1、$emit发射一个事件,事件的名称叫itemClick,发射事件的同时传递一个参数item。这个时候父组件需要监听这个事件
this.$emit('itemclick', item)
}
}
}
//父组件
const app = new Vue({
el: '#app',
data: {
message: 'hello'
},
components: {
cpn
},
methods: {
cpnclick(item) {
console.log(item)
}
}
})
</script>
</body>