文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

vue中如何实现非父子组件的通信

2023-06-29 04:44

关注

这篇文章主要介绍了vue中如何实现非父子组件的通信,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

一、Provide和Inject

ProvideInject用于非父子组件之间共享数据,比如有一些深度嵌套的组件,子组件想要获取父组件的数据,如果不存在Provide和Inject选项,我们可以通过props进行一次传递数据,但是这样做太过于繁琐。

对于上述情况,我们可以使用ProvideInject无论组件结构嵌套有多深,父组件都可以作为子组件数据的提供者。

父组件存在Provide来提供数据。

子组件存在Inject来获取数据。

在实际过程中,父组件不知道哪个子组件使用其数据,子组件也不知道使用的是哪个父组件的数据。

Provide和Inject的基本使用

//父组件<template>  <div>    <Content></Content>  </div></template><script>import Content from "./components/Content.vue";export default {  data() {    return {};  },  provide:{    name:"张三",    age:20  },  components: {    Content  }};</script><style scoped></style>
//子组件<template>  <div>    <h2>这里是Content组件</h2>    <h2>{{ name }} -- {{age}}</h2>    <ContentBase></ContentBase>  </div></template><script>import ContentBase from "./ContentBase.vue";export default {  data() {    return {};  },  components: {    ContentBase  },  inject:["name", "age"]};</script><style scoped></style>
//孙组件<template>  <div>      <h2>这里是contentBase组件</h2>      <h2>{{name}} -- {{age}}</h2>  </div></template><script>export default {  data() {    return {};  },  inject: ["name", "age"]};</script><style scoped></style>

最终显示结果为:

vue中如何实现非父子组件的通信

二、Provide和Inject的另一种写法

我们思考一种情况,如果Provide拿到的数据,是从data拿到的数据,此时如果获取? 此时this可以使用吗?

<template>  <div>    <Content></Content>  </div></template><script>import Content from "./components/Content.vue";export default {  data() {    return {      source: ["111","222", "333"]    };  },  provide:{    name:"张三",    age:20,    res: this.source.length   //我们在此时增加res,想要通过this.source.length拿到数组的长度  },  components: {    Content  }};</script><style scoped></style>

该结果是错误的。

vue中如何实现非父子组件的通信

报错信息显示,我们从undefined上读取属性,此时this为undefined。原因:从上面代码我们可以看出,this指向的是undefiend(因为this执行最外层)。

解决方法

我们将Provide设置为一个函数,并且返回一个对象,如下代码所示:

<template>  <div>    <Content></Content>  </div></template><script>import Content from "./components/Content.vue";export default {  data() {    return {      source: ["111", "222", "333"],    };  },  provide() {    return {      name: "张三",      age: 20,      res: this.source.length,    };  },  components: {    Content,  },};</script><style scoped></style>

显示结果:

vue中如何实现非父子组件的通信

此时我们再思考一个问题,如果我们向data数组中新增一个元素,在其他地方获取的数组长度会跟随变化吗?

<template>  <div>    <Content></Content>    <button @click="addOneItem">点击</button>  </div></template><script>import Content from "./components/Content.vue";export default {  data() {    return {      source: ["111", "222", "333"],    };  },  provide() {    return {      name: "张三",      age: 20,      res: this.source.length,    };  },  components: {    Content,  },  methods:{  //在这里添加点击事件    addOneItem() {      this.source.push("nnn")      console.log(this.source)    }  }};</script><style scoped></style>

vue中如何实现非父子组件的通信

vue中如何实现非父子组件的通信

结果如上图所示,可以看到数据是被添加进去的,但是子组件并没有检测到数据的变化。

此时我们可以使用computed来检测this.source.length的变化,使用代码如下所示。

<template>  <div>    <Content></Content>    <button @click="addOneItem">点击</button>  </div></template><script>import Content from "./components/Content.vue";import { computed } from "vue"   //从vue中引入computedexport default {  data() {    return {      source: ["111", "222", "333"],    };  },  provide() {    return {      name: "张三",      age: 20,      res: computed(() => this.source.length), //在这里添加computed    };  },  components: {    Content,  },  methods:{    addOneItem() {      this.source.push("nnn")      console.log(this.source)    }  }};</script><style scoped></style>

vue中如何实现非父子组件的通信

vue中如何实现非父子组件的通信

因为我们通过computed获取的是一个对象,此时我们通过value属性拿到值。

三、全局事件总线mitt库

在vue2时,如果我们使用事件总线可以使用this.$bus = new Vue()也就是实例化一个vue对象。但是我们在vue3中不能这样用。所以我们采用第三方库来实现组件之间的通信。这个第三方库为mitt

一、安装

npm install mitt

在文件中引入并且进行初始化导出。

import mitt from "mitt";const emitter = new mitt()export default emitter

监听事件,第一个参数是事件名,第二个参数是回调函数。

    emitter.on("why", (data) => {      console.log(data)    })    //*表示可以监听全部的事件。    emitter.on("*", (type, data) => {      console.log(type, data)    })

vue中如何实现非父子组件的通信

取消事件

//取消emitter中所有的监听emitter.all.clear()//或者//定义一个函数function onFoo(){}emitter.on("foo", onFoo)emitter.on("foo", onFoo)

感谢你能够认真阅读完这篇文章,希望小编分享的“vue中如何实现非父子组件的通信”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网行业资讯频道,更多相关知识等着你来学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯