1.简介
在开发中,往往有一些数据确实需要从上层传递到下层
比如,在一个页面中,我们从服务器中请求了很多数据
其中一些数据,并非是由整个页面的大组件来展示的,而是需要下面的子组件进行展示,这个时候,我们不会让子组件发送一个网络请求,而是让大组件把数据直接传给子组件
父子组件之间如何通信?
通过props向子组件传递数据
通过事件向父组件发送消息
2.父传子
props后面可以跟一个数组
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Title</title>
</head>
<body>
<div id="app">
<cpn :one="firstSentence" :two="secondSentence"></cpn>
</div>
<template id="cpnC">
<div>
<p>{{one}}</p>
<p>{{two}}</p>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const cpn = {
template: `#cpnC`,
props: ['one','two']
}
const app = new Vue({
el:'#app',
data: {
firstSentence: '人面不知何处去',
secondSentence: '桃花依旧笑春风',
},
components: {
cpn
}
})
</script>
</body>
</html>
当需要对props进行类型验证时,后面就要跟一个对象了(推荐)
代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Title</title>
</head>
<body>
<div id="app">
<cpn :cmovies="movies" :cmessage="message" :cmessage2="message2"></cpn>
</div>
<template id="cpnC">
<div>
<h2>{{cmessage}}</h2>
<ul>
<li v-for="item in cmovies">{{item}}</li>
</ul>
<h2>{{cmessage2}}</h2>
<ul>
<li v-for="item in csongs">{{item}}</li>
</ul>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const cpn = {
template: `#cpnC`,
props: {
//1.类型限制
cmovies: Array,
cmessage: [String, Number], //多个可能的类型
//2.提供一些默认值
cmessage2: {
type: String,
default: '这是默认值', //组件标签里若没有这句:cmessage2="message2",就显示默认值
required: true, //组件标签里必须要有这句:cmessage2="message2",也就是说必须要接受父组件的传值
},
//类型是对象或者数组时,默认值必须是一个函数
csongs: {
type: Array,
default(){
return ['我','是','默认值']
}
}
}
}
const app = new Vue({
el:'#app',
data: {
movies: ['《美国丽人》','《美丽人生》','《勇敢的心》','《超脱》'],
message: '你好',
message2: '当时只道是寻常',
songs: ['Cheap Hotel','I wanted you','Insomnia']
},
components: {
cpn
}
})
</script>
</body>
</html>
除此以外,props的验证也支持自定义类型
3.props驼峰标识
props后面用来接收父组件数据的变量,如果定义成小驼峰的格式,如cInfo,在动态绑定该变量的时候,不能直接用,要转化成小横线的格式
比如
<cpn :cInfo=“info” >这样写会报错
要改成<cpn :c-info=“info” >
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- 这里不能用驼峰标识cInfo,要转化成c-info-->
<cpn :c-info="info" :child-my-message="message"></cpn>
</div>
<template id="cpn">
<div>
<h2>{{cInfo}}</h2>
<h2>{{childMyMessage}}</h2>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const cpn = {
template: `#cpn`,
props: {
cInfo: {
type: Object,
default() {
return {};
}
},
childMyMessage: {
type: String,
default: '',
}
}
}
const app = new Vue({
el:'#app',
data:{
info: {
name: 'fyx',
age: 20,
height: 1.75,
},
message: '恒兀兀以穷年',
},
components: {
cpn
}
})
</script>
</body>
</html>
4.子传父
当子组件向父组件传递数据的时候,就要用到自定义事件
v-on指令不仅可以用于监听DOM事件,也可以用于监听组件间的自定义事件
具体流程:
在子组件中,用**$emit()**来触发事件
在父组件中,用v-on来监听子组件事件
代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Title</title>
</head>
<body>
<!--父组件模板-->
<div id="app">
<cpn @item-click="cpnClick"></cpn>
</div>
<!--子组件模板-->
<template id="cpn">
<div>
<button v-for="item in categories" @click="btnClick(item)">{{item.name}}</button>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
//子组件
const cpn = {
template: `#cpn`,
data() {
return {
categories: [
{id: 'rmtj', name: '热门推荐'},
{id: 'sjsm', name: '手机数码'},
{id: 'jyjd', name: '家用家电'},
{id: 'dnbg', name: '电脑办公'},
]
}
},
methods: {
btnClick(item){
//发射事件
this.$emit('item-click',item)
}
}
}
//父组件
const app = new Vue({
el:'#app',
methods: {
cpnClick(item){
console.log('cpnClick',item);
}
},
components: {
cpn
}
})
</script>
</body>
</html>