亲宝软件园·资讯

展开

Vue非父子组件通信

林有酒 人气:0

非父子组件的通信

此篇讲解的是, 在学习状态管理之前, 非父子间通信的方案

在开发中,我们构建了组件树之后,除了父子组件之间的通信之外,还会有非父子组件之间的通信

这里我们主要讲两种方式

1.Provide和Inject

1.1基本使用

Provide/Inject用于非父子组件之间共享数据

对于这种情况下,我们可以使用 Provide 和 Inject

实际上,你可以将依赖注入看作是“long range props”,除了

我们开发一个下面这样的结构: 让App.vue提供一些数据给HomeContent.vue使用[外链图片转存失败,

在祖先组件中通过provide将数据传出, provide对应的是一个对象

export default {
  components: {
    Home
  },
  // 通过provide将数据传出
	provide() {
		return {
			name: this.name,
			age: this.age,
			height: this.height
		}
	}
}

在后代元素中, 通过inject接收祖先传递的数据, inject对应的是一个数组

export default {
  inject: ["name", "age", "height"]
}

1.2处理响应式数据(了解)

我们先来验证一个结果:如果我们修改了this.names的内容,那么使用length的子组件会不会是响应式的?

<template>
  <div class="app">
    <home />
    <h2>{{ name }}</h2>
    <button @click="btnClick">按钮</button>
  </div>
</template>

<script>
  import Home from './Home.vue'

  export default {
    components: {
      Home
    },
    data() {
      return {
        name: "chenyq",
        age: 18,
        height: 1.88,
      }
    },
    // 通过provide将数据传出
    provide() {
      return {
        name: this.name,
        age: this.age,
        height: this.height
      }
    },
    methods: {
      btnClick() {
        this.name = "kaisa"
      }
    },
  }
</script>

我们会发现对应的子组件中是没有反应的

这是因为当我们修改了names之后,之前在provide中引入的 this.name 本身并不是响应式的

那么怎么样可以让我们的数据变成响应式的呢?

import { computed } from 'vue'

export default {
  components: {
    Home
  },
  data() {
    return {
      name: "chenyq",
      age: 18,
      height: 1.88,
    }
  },
  // 通过provide将数据传出
  provide() {
    return {
      name: computed(() => this.name),
      age: this.age,
      height: this.name
    }
  },
  methods: {
    btnClick() {
      this.name = "kaisa"
    }
  },
}

注意:我们在使用name的时候需要获取其中的value

这是因为computed返回的是一个ref对象,需要取出其中的value来使用;

<template>
  <div class="home-content">
    <h2>名字: {{ name.value }}, 年龄: {{ age}}, 身高: {{ height}}</h2>
  </div>
</template>

2.全局事件总线

Vue3从实例中移除了 o n 、 on、 on、off 和 $once 方法,所以我们如果希望继续使用全局事件总线,要通过第三方的库

首先,我们需要先安装这个库npm install hy-event-store

其次,我们可以封装一个工具eventbus.js

import { HyEventBus } from "hy-event-store";
const eventBus = new HyEventBus()
export default eventBus

在项目中导入后可以使用它们

Banner中触发事件:

<template>
  <div class="home-content">
    <button @click="btnClick">按钮</button>
  </div>
</template>

<script>
  import eventBus from './utils/event-bus'

  export default {
    methods: {
      btnClick() {
        console.log("myEvent事件被监听")
				// 发送事件到事件总线上
        eventBus.emit("myEvent", "chenyq", 18, 1.88)
      }
    },
  }
</script>

App中监听事件:

<script>
  import eventBus from './utils/event-bus'
  import Home from './Home.vue'

  export default {
    components: {
      Home
    },
    created() {
			// 监听事件总线上的事件
      eventBus.on("myEvent", (name, age, height) => {
        console.log(name, age, height)
      })
    },
  }
</script>

总结

加载全部内容

相关教程
猜你喜欢
用户评论