vue 中组件通信总共分为四种,父子组件通信,子父组件通信,兄弟组件通信
1. 父子通信
- 父组件通过属性绑定方式,向自子组件传递数据
- 子组件通过props 接受父组件传递的数据,props 有两种形式,一种形式是数组,另一种形式是对象,对象比数组的好处是,对象可以对当前传递的数据进行个性化配置
数组形式的 props
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<child :msg="msg"></child>
</div>
<script src="./js/vue.js"></script>
<script>
Vue.component('child', {
template: `
<div>
<p>{{msg}}</p>
</div>
`,
props:['msg']
})
new Vue({
el: '#app',
data: {
msg: '这是父组件传递的数据'
}
})
</script>
</body>
</html>
对象形式的 props
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<child :msg="msg"></child>
</div>
<script src="./js/vue.js"></script>
<script>
Vue.component('child', {
template: `
<div>
<p>{{msg}}</p>
</div>
`,
props: {
msg: {
default: '这是子组件默认的数据',
type:String,
required: true
}
}
})
new Vue({
el: '#app',
data: {
msg: '这是父组件传递的数据'
}
})
</script>
</body>
</html>
2. 子父通信
- 子组件通过 $emit 触发自定义事件,并传递数据
- 父组件通过监听自定义事件来判断子组件是否触发
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<child @cp="handle($event)" :msg="msg"></child>
</div>
<script src="./js/vue.js"></script>
<script>
Vue.component('child', {
template: `
<div>
<p @click="child">{{msg}}</p>
</div>
`,
props: {
msg: {
default: '这是子组件默认的数据',
type:String,
required: true
}
},
methods: {
child() {
this.$emit('cp', '这是子组件传递的数据')
}
}
})
new Vue({
el: '#app',
data: {
msg: '这是父组件传递的数据'
},
methods: {
handle(val) {
console.log(val);
}
}
})
</script>
</body>
</html>
3. 兄弟组件通信
- 通过事件总线的方式去触发,事件总线就是一个 vue的实例对象,我们通过 on监听的事件,emit 触发的事件都在这个 vue 的实例对象里面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<child1></child1>
<child2></child2>
</div>
<script src="./js/vue.js"></script>
<script>
var hub = new Vue()
Vue.component('child1', {
template:`
<div>
<p>这是兄弟组件一</p>
<button @click="changeTwo">传递给兄弟组件二</button>
</div>
`,
methods: {
changeTwo() {
hub.$emit('change-two', '这是兄弟组件一传递的数据')
}
},
mounted() {
hub.$on('change-one', (val) => {
console.log(val);
})
}
})
Vue.component('child2', {
template:`
<div>
<p>这是兄弟组件二</p>
<button @click="changeOne">传递给兄弟组件一</button>
</div>
`,
methods: {
changeOne() {
hub.$emit('change-one', '这是兄弟组件二传递的数据')
}
},
mounted() {
hub.$on('change-two', (val) => {
console.log(val);
})
}
})
new Vue({
el: '#app'
})
</script>
</body>
</html>
4.依赖注入
- provide 与 inject的传值与 props 类似,前者可以给后代组件传值,而props是只能给子组件传值。
- 使用 provide与inject 方法传值,如果值修改后面组件的值是不会跟着变得,也就是说值不会响应,(这种方式也是单向数据轻易不要修改)
- 一般使用在组件封装当中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<father></father>
</div>
<script src="./js/vue.js"></script>
<script>
Vue.component('father', {
template: `
<div>
<son></son>
</div>
`
})
Vue.component('son', {
template: `
<div>
<p>这是son 组件</p>
<p>{{foo}}</p>
</div>
`,
inject: {
foo: {
default: 'foo'
}
}
})
new Vue({
el: '#app',
provide: {
foo: 'bar'
}
})
</script>
</body>
</html>