浅谈Vue组件之间通信的五种方式

为什么需要使用组件通信?

组件是一个孤岛,所有的组件都无法直接访问其他组件的data,methods,computed,也就说每个组件都是一个局部作用域,这样做的目的是为了保护私有变量,保证每个组件之间的data不会相互影响.
但是在vue中我们经常需要在组件之间进行通信,下面我就来说说组件之间的几种通信方式:

父子组件之间通信原理大致就是如图所示:
父子组件之间通信

1.父传子

父传子我们一般通过动态绑定属性的方式获取,即在子组件标签上绑定属性,然后在子组件中用props来接收.

<body>
  <!-- 父组件 -->
  <div id="app">
    <!-- 子组件 -->
    <child mytitle="home" :mytext="text" :myshow='true'></child> 
  </div>
</body>
</html>
<script>
  // 全局组测的子组件
  Vue.component("child",{
    template:`
            <div>
              <button v-if="myshow">返回</button>
              <span>我是导航栏--{{mytitle}}--{{mytext}}</span>
              <button v-show="myshow">主页</button>
            </div>
            `,
    // props:["mytitle","mytext","myshow"],数组方式接收
    props:{  //对象方式接收,可以定义接收的数据类型
      mytitle:String,
      mytext:String,
      myshow:Boolean
    }
  })
  var vm=new Vue({
    el:"#app",
    data:{
      text:"我是在父组件中定义的",
    }
  })
</script>
2.子传父

子传父通过事件绑定的方式进行传递: 在子组件标签上绑定事件,在子组件中用this.$ emit来触发事件执行函数,并且可以传递参数即this.$ emit(“事件”,参数),函数在父组件中执行后就可以得到传递过来的参数.

<body>
  <!-- 父组件 -->
  <div id="app">
    <!-- 子组件 -->
    <!-- 在子组件上绑定两个事件event1和event2 -->
    <!-- 事件后面的函数如果加括号的话,参数要写成$event才能接收到,
    不加括号的话默认能接收到,推荐不加括号 -->
    <my-child @event1="handleEvent1($event)" @event2="handleEvent2">
    </my-child>
  </div>
</body>
</html>
<script>
  Vue.component("myChild",{
    template:`
    <div>
      child-<button @click="handleClick()">Click</button>  
    </div>
    `,
    data(){
      return {
        text:"child定义的状态"
      }
    },
    methods:{
      handleClick(){
        // 子组件中通过this.$emit来触发绑定的事件并进行传参
        this.$emit("event1",1000000000)
        this.$emit("event2",this.text)
      }
    }
  })

  var vm=new Vue({
    el:"#app",
    methods:{
      // 事件被触发执行后,函数会收到子组件传过来的参数
      handleEvent1(data){
         console.log("收到钱了--1",data)  // 收到钱了--1 1000000000
      },
      handleEvent2(data){
        console.log("收到了--2",data)  // 收到了--2 child定义的状态
      }
    }
  })
</script>
3.通过给组件绑定ref属性来进行通信

ref绑定在组件上,可以通过this.refs拿到组件对象. ref绑定在dom节点上,通过this.refs拿到的是原生dom节点.
但是这种方式太过暴力,暴露了vue并不是严格的MVVM模式,所有组件都可以随意修改拿到后的数据,所以不推荐使用.

<body>
  <div id="app">
    <!-- 绑定在标签上 -->
    <input type="text" ref="mytext">
    <button @click="handleClick()">Click</button>
    <!-- 绑定在组件上 -->
    <child1 ref="mychild"></child1>
  </div>
  
</body>
</html>
<script>
  Vue.component("child1",{
    template:`
    <div>{{name}}</div>
    `,
    data(){
      return {
        name:"Stephen--child1定义的"
      }
    }
  })
  var vm=new Vue({
    el:"#app",
    data:{

    },
    methods:{
     handleClick(){
       console.log(this.$refs.mytext.value) //可以拿到输入框的值
      console.log(this.$refs.mychild.name) // (Stephen--child1定义的)
      this.$refs.mychild.name="Kerwin" //可以随意修改
      console.log(this.$refs.mychild.name) //kerwin
     }
    }
  })
</script>
4.中央事件总线

中央事件总线通信原理图:
在这里插入图片描述

中央事件总线通过重新new一个vue实例Bus,需要传递数据的组件可以通过bus.$ emit将数据传输给Bus,需要接收数据的组件则通过bus.$ on来接收传给Bus的数据.即this.$ emit(‘事件名’,参数)传送, this.$on(‘事件名’,(data)=>{})接收,bus通信一般用在非父子组件之间进行通信,比如下面例子中的child1hechild2兄弟组件之间.

<script>
  var bus = new Vue() //中央事件总线 bus.$on接收,bus.$emit传送
  // 组件1
  Vue.component("child1", {
    template: `
          <div>
            child1-<button @click="handleClick()">click</button>
          </div>
        `,
    methods: {
      handleClick() {
        bus.$emit("kerwinevent", "来自child1的问候") //将组件1里面的参数
        //通过事件kerwinevent
        //以bus.$emit的方式传送给bus中央事件总线
      }
    },
  })
  // 组件2
  Vue.component("child2", {
    template: `
          <div>
            child2
            {{str}} 
          </div>
        `,
    data() {
      return {
        str: ""
      }
    },
    mounted() {
      bus.$on("kerwinevent", (data) => { //组件2中通过bus.$on的方式
      //从bus中央事件总线上接收对应事件kerwinevent的数据
        this.str = data  //"来自child1的问候"
      })
    }
  })
  var vm = new Vue({
    el: "#app",
  })
</script>
5.状态管理 Vuex

在大型组件开发项目中,通信会变得越来越频繁,不同组件之间的关系变得越来越复杂,异步请求的数据需要重复使用,这时候我们就需要用到vuex了.

首先vuex是什么?

官方定义:Vuex是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.
我的理解:也就是说在项目中我们需要共享的状态,不同页面(组件)之间需要共享的ajax请求数据,都可以存到vuex中,然后以一定的规则进行存储和拿取.

vuex的状态管理模式:
vuex的状态管理模式图

  1. state:单一状态树 ,每个应用将仅仅包含一个 store 实例。
  2. getters:可以从store 中的state 中派生出一些状态,getters的返回值会根 据 它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。可以认为是store 的计算属性
  3. mutations:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。
  4. actions: Action 提交的是 mutation,而不是直接变更状态。 Action 可
    以包含任意异步操作。

什么情况下我应该使用 Vuex?
Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

结尾:以上就是我对vuex中组件间的通信技术的总结,不足的地方望补充(逆战班).

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值