- props / $emit
父组件通过props向子组件传递数据,子组件通过$emit和父组件通信
props只能是父组件向子组件进行传值
// 父组件代码
<template>
<div class="home">
<hello-world :msg="msg" @onMsg="toMsg"></hello-world>
<br>
<span>子组件传递过来的:{{msg_new}}</span>
</div>
</template>
<script>
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'HomeView',
components: {
HelloWorld
},
data(){
return{
msg: "我是父组件传递下去的值",
msg_new: ""
}
},
methods: {
toMsg(p){
this.msg_new = p
}
}
}
</script>
// 子组件代码
<template>
<div class="hello">
<p>父组件传递下来的:{{ msg }}</p>
<button @click="goMsg">把值传递给父组件</button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: ['msg'],
methods: {
goMsg(){
// 定义自定义函数 将值传递给父组件
this.$emit('onMsg',"567")
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
- eventBus事件总线($emit / $on)
兄弟组件之间的通信
利用 $emit 发送,则 $on 接收
// 父组件
<template>
<div class="about">
<event-b-one></event-b-one>
<event-b-two></event-b-two>
</div>
</template>
<script>
import eventB_one from '@/components/eventB_one.vue'
import eventB_two from '@/components/eventB_two.vue'
export default{
components: {
eventB_one,eventB_two
}
}
</script>
// 子组件
<template>
<div>
<button @click="goEventB">我传给兄弟eventB_two</button>
</div>
</template>
<script>
import {EventBus} from './event-bus.js'
export default {
name: 'eventB_one',
data(){
return{
num: 0
}
},
methods: {
goEventB(){
EventBus.$emit('addition',{
num: this.num++
})
}
}
}
</script>
<style lang="less" scoped>
</style>
// 子组件
<template>
<div>
{{count}}
</div>
</template>
<script>
import {EventBus} from './event-bus.js'
export default {
name: 'eventB_two',
data(){
return{
count: 0
}
},
mounted(){
EventBus.$on('addition', (p) => {
console.log(p);
})
}
}
</script>
<style lang="less" scoped>
</style>
- 依赖注入(provide / inject)
父子 父孙之间的组件通信
provide 钩子用来发送数据或方法
inject钩子用来接收数据或方法
<template>
<div>
<aprovide></aprovide>
</div>
</template>
<script>
import Aprovide from '@/components/Aprovide.vue'
export default {
components: {
Aprovide
},
// 发送数据或方法
provide(){
return{
num: 10
}
}
}
</script>
<style lang="less" scoped>
</style>
<template>
<div>
儿子组件:我接收了:{{num}}
<bprovide></bprovide>
</div>
</template>
<script>
import Bprovide from './Bprovide.vue'
export default {
components: {
Bprovide
},
// 接收数据或方法
inject:['num']
}
</script>
<style lang="less" scoped>
</style>
<template>
<div>
孙子组件:我也接收了{{num}}
</div>
</template>
<script>
export default {
// 接收数据或方法
inject:['num']
}
</script>
<style lang="less" scoped>
</style>
- ref / $refs
ref属性是指向子组件的实例,通过实例来访问子组件的数据与方法
// 父组件
<template>
<div>
<ref ref="child"></ref>
<button @click="go">加子组件的数</button>
</div>
</template>
<script>
import ref from '@/components/ref.vue'
export default {
components: {ref},
methods: {
go(){
this.$refs.child.sayHello()
}
}
}
</script>
<style lang="less" scoped>
</style>
// 子组件
<template>
<div>
我是子组件:{{num}}
</div>
</template>
<script>
export default {
data(){
return{
num: 0
}
},
methods: {
sayHello () {
this.num++
}
}
}
</script>
<style lang="less" scoped>
</style>
- $parent / $children
$parent 访问父组件的实例
$children 访问子组件的实例
// 父组件
<template>
<div>
我是父组件:{{num}}
<button @click="add">获取子组件的变量</button>
<parent></parent>
</div>
</template>
<script>
import parent from '@/components/parent.vue'
export default {
name: "parentView",
components:{parent},
data(){
return{
num: 0
}
},
mounted(){
// 获取子组件的所有实例 并且返回的是一个array的数组
console.log(this.$children);
},
methods: {
addNum(){
this.num++;
}
}
}
</script>
<style lang="less" scoped>
</style>
// 子组件
<template>
<div>
<button @click="addNum">我是子组件的事件</button>
</div>
</template>
<script>
export default {
name: "parent",
data(){
return{
msg1: "我是子组件的变量",
msg2: "我是子组件的变量",
msg3: "我是子组件的变量",
}
},
methods: {
addNum(){
// 通过 $parent 访问父组件的实例
this.$parent.addNum()
// 以及变量
console.log(this.$parent.num);
}
}
}
</script>
<style lang="less" scoped>
</style>
- $attrs / $listeners
实现组件之间的跨代通信
// 父组件
<template>
<div>
<attrs :msg1="1" :msg2="2"></attrs>
</div>
</template>
<script>
import attrs from '@/components/attrs.vue'
export default {
components:{attrs}
}
</script>
<style lang="less" scoped>
</style>
// 子组件
<template>
<div>
我是子组件--{{msg1}}
$attrs: {{$attrs}}
<!-- v-bind="$attrs" 将值绑定 -->
<attrs-view v-bind="$attrs"></attrs-view>
</div>
</template>
<script>
import attrsView from '@/components/attrsView.vue'
export default {
components:{attrsView},
props: ['msg1'],
// inheritAttrs: false,
}
</script>
<style lang="less" scoped>
</style>
// 子组件下的子组件
<template>
<div>
我是子组件的子组件--{{msg2}}
</div>
</template>
<script>
export default {
props: ['msg2'],
inheritAttrs: false,
}
</script>
<style lang="less" scoped>
</style>
- 总结 - 组件间通信
- 子组件通过注册监听事件,通过$emit来向父组件发送
- 通过ref属性给子组件设置一个名字,可以访问子组件的实例 - this.$refs.自定义名字.
- 而子组件通过 this. p a r e n t 来访问父组件的实例,相反父组件通过 t h i s . parent 来访问父组件的实例,相反 父组件通过 this. parent来访问父组件的实例,相反父组件通过this.chilerdn 来子组件的实例,这个返回是一个数组,而且返回顺序是不定的
- 祖孙通信:通过 provide() 定义变量,接下来 inject 去接收变量
- 兄弟组件:通过 new Vue() 一个实例作为组件间的中心点,发送使用 $emit() 接收使用 $on()