Vue父子组件(1)
父子组件通信——父传子props:
之前我们提到了子组件是不能引用父组件或者Vue实例的数据的,但在开发中往往一些数据需要从上层传到下层
- 比如一个页面中,我们从服务器请求到很多数据
- 其中一部分数据,并非我们整个页面的大组件来展示的,而是需要下面的子组件来展示
- 子组件并不会再发送一次网络请求,这时候就需要让大组件(父组件)将数据传递给小组件(子组件)
如何进行父子组件的数据通信呢?
- 通过props向子组件传递数据
- 通过事件向父组件发送消息emit
通过props向子组件传递数据:
<div id="app">
<cpn v-bind:cmovies="movies" :cmessage="message"></cpn>
</div>
<!-- 组件模板分离写法 -->
<template id="cpn">
<div>
{{cmessage}}
<ul>
<li v-for="(item,index) in cmovies">{{index}}--{{item}}</li>
</ul>
</div>
</template>
<script src="js/vue.js"></script>
<script>
const cpn = {
template: '#cpn',
//父组件向子组件传递的参数声明
//1.数组
//props: ['cmovies','cmessage'],
props: {//对象写法
//2.类型限制
// cmovies: Array,
// cmessage: String
//3.提供一些默认值
cmessage: {
type: String,
default: 'aaaaaa',
required: true //必须传值,不传会报错
},
cmovies: {
//类型是对象或者数组时,默认值必须是一个函数
type: Array,
default() {
return []
}
}
},
data() {
return {}
}
};
const app = new Vue({
el: '#app',
data: {
message: 'abc',
movies: ['aaa','bbb','ccc','ddd','eee']
},
components: {
//'cpn':{}注册组件语法糖
cpn
}
})
</script>
props中的驼峰标识:
因为 v-bind当前不支持驼峰标识的识别,所以在props中命名变量时尽量避免驼峰命名,如果使用驼峰命名,则在v-bind绑定动态数据时要将驼峰命名变量名进行转换,转换方法如下
例:cInfo ==> v-bind:c-info,childMyMessage ==> child-my-message
驼峰标识写法改成-加首字母小写
父子组件通信——子请求父emit:
什么时候需要自定义事件呢?
当子组件需要向父组件传递数据时,就要用到自定义事件了
我们之前学的v-on不仅可以用于监听DOM事件,还可以用于组件间的自定义事件
自定义事件的流程:
在子组件中,通过$emit来触发事件
在父组件中,用v-on来监听子组件时间
<!-- 父组件模板 -->
<div id="app">
<!-- 父组件监听事件itemClick -->
<!-- 因为cpnclick是自定义的事件,所以浏览器不自动生成event事件 -->
<!-- 这里不带括号默认的传入值就收catalog -->
<cpn @itemclick="cpnclick"></cpn>
</div>
<!-- 子组件模板 -->
<template id='cpn'>
<div>
<!-- 点击按钮触发事件 -->
<button v-for="(catagory,index) in catagories" @click='btnclick(catagory)'>{{catagory.name}}</button>
</div>
</template>
<script src="js/vue.js"></script>
<script>
//1.子组件
const cpn = {
template: `#cpn`,
data () {
return {
catagories: [
{id: 'aaa', name: '热门推荐'},
{id: 'bbb', name: '手机数码'},
{id: 'ccc', name: '家用电器'},
{id: 'ddd', name: '电脑办公'},
]
}
},
methods: {
btnclick(catagory) {
//子组件向父组件发送数据(自定义事件),父组件监听
this.$emit('itemclick', catagory)
}
}
}
//2.父组件
const app = new Vue({
el: '#app',
data: {
info: {
name: '小明',
sex: '男',
age: 23,
},
msg: "hello Vue"
},
methods: {
cpnclick(catagory){
console.log(catagory.name)
}
},
components: {
cpn
}
})
</script>