首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue组件通信的三种方式

Vue组件通信的三种方式

作者头像
姜同学
发布2022-10-27 17:15:55
4300
发布2022-10-27 17:15:55
举报
文章被收录于专栏:姜同学姜同学

我们都知道Vue是一款渐进式的js框架,在开发大型应用的时候,Vue官方推荐你使用组件化进行开发,即每一个页面都是一个组件,一个组件内包含了一个或多个组件,下面举一个简单的例子描述一下Vue中的组件。

github-search
github-search

如上一个简单的搜索Github用户的单页面应用可以分为搜索组件和列表组件,当然如果你非要较真的的话一个列表组件是由一个又一个的itme组成的我也不反对,不过为了方便编写测试代码,我将其分为搜索组件和列表组件,很明显search这个动作是在搜索组件中发起的,搜索组件如何把请求到的数据交给列表组件呢,这就要谈一谈Vue中常见的三种组件通信方式啦。

全局事件总线

Vue 原型对象上包含事件处理的方法:

  1. $on(eventName, listener): 绑定自定义事件监听
  2. $emit(eventName, data): 分发自定义事件
  3. $off(eventName): 解绑自定义事件监听
  4. $once(eventName, listener): 绑定事件监听, 但只能处理一次

又因为所有组件实例对象的原型对象的原型对象就是 Vue 的原型对象

  1. 所有组件对象都能看到 Vue 原型对象上的属性和方法
  2. Vue.prototype.bus = new Vue(), 所有的组件对象都能看到bus 这个属性 对象

so这个$bus就是全局事件总线,我们可以使用他的绑定自定义事件和分发自定义事件来进行组件间的通信,步骤也是非常的easy哇,只需要简简单单的三步即可完成组件的通信

1.在main.js中绑定全局事件总线

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = true

new Vue({
  render: h => h(App),
  beforeCreate () { // 尽量早的执行挂载全局事件总线对象的操作
    Vue.prototype.$bus = this
    }
}).$mount('#app')

2.列表组件$on绑定自定义事件

export default {
  name: "List",
  data() {
    return {
      info: {
        userList: [],
        isFirst: true,
        isLoading: false,
        errMsg: ''
      },
    };
  },
  mounted() {
    this.$bus.$on("getUserList", (info) => { // 绑定自定义事件
      console.log("@@", "收到回调", info);

      this.info = {...this.info,...info};
    });
  },
  props: {},
};

3.搜索组件$emit分发自定义事件

axios.get("https://api.github.com/search/users?q=" + this.keyword).then(
            (response) => {
            console.log("@@", "请求成功啦"),
                this.userList = response.data.items,
                this.$bus.$emit("getUserList", { // 发送自定义事件
                     userList: this.userList,
                     isFirst: false,
                     isLoading: false
                });
            },

            (error) => {
            console.error("@@", "请求失败啦");
            this.$bus.$emit("getUserList", {
                     userList: [],
                     isFirst: false,
                     isLoading: false,
                     errMsg: error.message
                });
            }
        );

消息的发布订阅

消息的发布订阅使用过消息中间件的同学想必对此不会陌生吧,搜索组件是消息的生产者,列表组件是消息的的消费者,生产者和消费者都有了,那谁是消息中间件哇,e’m’m~消息中间件自然就是Vue支持的各种各样的消息订阅的第三方库啦,我这一个前端菜鸡也不推荐你哪个库好用,因为我只会用PubSubJs,使用方法也是very的easy哇。

1.安装注册pubsubjs

import pubsub from 'pubsub-js'; // 哪里用到就在那里导入

2.列表组件订阅消息

mounted() {
     pubsub.subscribe("getUserList",(msgName,info) => { // 订阅消息
         console.log("@@", "收到回调", msgName,info);
         this.info = {...this.info,...info};
     })
  }

3.搜索组件发布消息

searchUsers() {
        axios.get("https://api.github.com/search/users?q=" + this.keyword).then(
            (response) => {
            console.log("@@", "请求成功啦"),
                this.userList = response.data.items,
                pubsub.publish("getUserList",{ // 发布消息
                userList: this.userList,
                isFirst: false,
                isLoading: false,
                errMsg: ''
             })
            }
            }
        );
        }

4.最后别忘了在Vue生命周期中的beforeDestroy()上取消消息的订阅哦

beforeDestroy(){
	PubSub.unsubscribe(subscribeId) //pubsub.subscribe的返回值就是subscribeId
}

Vuex共享状态

写着写着我发现把Vuex放在这里不太合适,因为Vuex官方给出的定义是Vuex是用来给大型单页面应用共享状态的,而不是负责组件通信的,但是既然都写了,还是把它放到这里吧。

### 每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)

如下是官方给Vuex的定义,简单的来说无非就是Vuex有一个store他保存着Vue全局的共享状态,因为这是Vuex的官方插件,使用Vue.use(Vuex)之后Vue实例对象就有了$store这个属性,你就可以让着他对共享状态为所欲为了,在我们的搜索案例里,我们就把列表里面的用户信息当作是一个共享状态就好了啦

Vuex
Vuex

1.快速安装Vuex

如果你用的是Vue2.x的脚手架注意安装Vuex3.x才可以哦。

npm install vuex
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store ({
    state: {
        userInfo: []
    },
    mutations: {
      setUserInfo (state,userInfo) {
        state.userInfo = userInfo;
      }
    }
  })

2.搜索组件commit改变共享状态

axios.get("https://api.github.com/search/users?q=" + this.keyword).then(
            response => {
            console.log("@@", "请求成功啦"),
                this.userList = response.data.items,
                this.$store.commit('setUserInfo',{ // commit
                userList: this.userList,
                isFirst: false,
                isLoading: false,
                errMsg: ''
             })
            },

3.列表组件展示共享状态$store.state

<div class="card" v-for="user in $store.state.userInfo.userList" :key="user.id"> // here
      <a :href="user.html_url" target="_blank">
        <img :src="user.avatar_url" style="width: 100px" />
      </a>
      <p class="card-text">{{ user.login }}</p>
</div>
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-08-06T,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 全局事件总线
    • 1.在main.js中绑定全局事件总线
      • 2.列表组件$on绑定自定义事件
        • 3.搜索组件$emit分发自定义事件
        • 消息的发布订阅
          • 1.安装注册pubsubjs
            • 2.列表组件订阅消息
              • 3.搜索组件发布消息
                • 4.最后别忘了在Vue生命周期中的beforeDestroy()上取消消息的订阅哦
                  • Vuex共享状态
                    • 1.快速安装Vuex
                      • 2.搜索组件commit改变共享状态
                        • 3.列表组件展示共享状态$store.state
                        相关产品与服务
                        事件总线
                        腾讯云事件总线(EventBridge)是一款安全,稳定,高效的云上事件连接器,作为流数据和事件的自动收集、处理、分发管道,通过可视化的配置,实现事件源(例如:Kafka,审计,数据库等)和目标对象(例如:CLS,SCF等)的快速连接,当前 EventBridge 已接入 100+ 云上服务,助力分布式事件驱动架构的快速构建。
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档