vue组件通信的6种方式

介绍

首先组件作为vue.js最强大的功能之一,而且组件实例的作用域都是相互独立的,所以不同组件之间的数据无法相互进行直接的引用,因此组件间的相互通信是非常重要的。

这里介绍几种常见的通信方式:

  • 父子之间

  • 子父之间

  • 兄弟之间

  • 其他通信方式

  1. 父传子

  • 在父组件中,用 v-bind 动态绑定一个自定义属性,用于给子组件传递数据

父组件
<template>
  <div>
    <child :users="user"></child>
  </div>
</template>
 
<script>
import { child } from "./child";
export default {
  components: { child },
  data() {
    return {
      user: '李四'
    };
  }
};
</script>
  • 在子组件中,使用 props 接收父组件传过来的数据。

<template>
  <div>{
    
    { users }}</div>
</template>
 
<script>
export default {
  props: ["users"]
};
</script>
  1. 子传父

  • 子组件通过事件的方式,利用 $emit 给父组件传值。

  • 注意:$emit 的第一个参数是父组件自定义事件的方法名,后边的 “value” 是子组件要给父组件传递的数据

子组件
<template>
  <div>
    <button @click="datas"></button>
  </div>
</template>
 
<script>
export default {
  methods: {
    datas() {
      this.$emit("info", value);
    }
  }
};
</script>
  • 在父组件中,绑定一个自定义事件,用来接收子组件传来的值;

<template>
  <div>
    <child @info="getInfo"></child>
  </div>
</template>
 
<script>
import { child } from "./child";
export default {
  components: { child },
  methods: {
    getInfo(value) {
      // value 就是子组件传递过来的数据
    }
  }
};
</script>
  1. 兄弟之间

eventBus事件总线适用于任意两个组件之间的通信,使用步骤如下:

// 方法一:
// 创建一个单独的 js文件 EventBus.js,然后在需要的地方引入
// EventBus.js 
import  vue  from "vue" 
ecport default new Vue()

// 方法二:
// 直接挂载在全局
// main.js 
import  vue  from "vue" 
Vue.prototype.$EventBus = new Vue()

// 方法三:
// 注入到Vue 跟对象上
// main.js 
import  vue  from "vue"  
new Vue ({
    el:"#app",
    data:{
        EventBus:new Vue()
        }
})

在需要发送的组件中发送事件:

<template>
  <div>
    <button @click="add">加法</button>    
  </div>
</template>

<script>
import {EventBus} from './EventBus.js' // 引入事件中心

export default {
  data(){
    return{
      num:0
    }
  },
  methods:{
    add(){
      EventBus.$emit('addition', {
        num:this.num++
      })
    }
  }
}
</script>

在接收组将中接收

<template>
  <div>求和: {
    
    {count}}</div>
</template>

<script>
import { EventBus } from './EventBus.js'
export default {
  data() {
    return {
      count: 0
    }
  },
  mounted() {
    EventBus.$on('addition', param => {
      this.count = this.count + param.num;
    })
  },
   beforeDestory(){
        // 取消监听
       EventBus.off("addition")
    }
}
</script>

用 $emit去监听,用$on去触发,注意需要$off来取消监听,否则可能会造成内存泄漏。

  1. ref / $refs

这种方式也是实现父子组件之间的通信

ref:这个属性用在子组件上,它的用用就指向了子组件的实例,可以通过实例来访问组件的数据和方法

在子组件中:


export default {
  data () {
    return {
      name: 'JavaScript'
    }
  },
  methods: {
    sayHello () {
      console.log('hello')
    }
  }
}

在父组件中

<template>
  <child ref="child"></component-a>
</template>
<script>
  import child from './child.vue'
  export default {
    components: { child },
    mounted () {
      console.log(this.$refs.child.name);  // JavaScript
      this.$refs.child.sayHello();  // hello
    }
  }
</script>
  1. $parent / $children

  • 使用$parent可以让组件访问父组件的实例(访问的是上一级父组件的属性和方法)。

  • 使用 $children 可以让组件访问子组件的实例,但是, $children 并不能保证顺序,并且访问的数据也不是响应式的。

  • 注意:仅限于父子组件之间,不推荐使用,因为不利于维护,一旦组件层次发生了变化,就需要更改其中的层次关系

子组件中:

<template>
  <div>
    <span>{
    
    {message}}</span>
    <p>获取父组件的值为:  {
    
    {parentValue}}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Vue'
    }
  },
  computed:{
    parentVal(){
      return this.$parent.parentMsg;
    }
  }
}
</script>

父组件中:

<template>
  <div class="hello_world">
    <div>{
    
    {msg}}</div>
    <child></child>
    <button @click="change">点击改变子组件值</button>
  </div>
</template>

<script>
import child from './child.vue'
export default {
  components: { child },
  data() {
    return {
      parentMsg: 'Welcome'
    }
  },
  methods: {
    change() {
      // 获取到子组件
      this.$children[0].message = 'JavaScript'
    }
  }
}
</script>

在上面的代码中,子组件获取到了父组件的parentValue值,父组件改变了子组件中message的值。

  1. 依赖注入(provide / inject)

  • 这种方式就是vue中依赖注入,该方法用于 父子组件之间 的通信。当然这里所说的父子不一定是真正的父子,也可以是祖孙组件,在层数很深的情况下,可以使用这种方式来进行传值。就不用一层一层的传递数据了。

  • provide和inject是vue提供的两个钩子,和data、methods是同级的。并且provide的书写形式和data一样。

  • provide 钩子用来发送数据或方法。

  • inject钩子用来接收数据或方法

// 父组件
exportdefault{
provide(){
    return {
        message:'hellow world !'    
        }    
    }
}

// 后代组件

export default{
    inject:['message']
} 

缺陷:传递的数据不是响应式的,inject接收到数据后,provide中的数据改变,但是后代组件中的数据不会改变。所以 建议传一些常量或者方法。

猜你喜欢

转载自blog.csdn.net/hudabao888666/article/details/129004482