Vue3 非父组件的通信

2022/7/21 vue2vue3js

两种方法

# Provide/Inject

  • 有两种写法 第一种 对象写法 只能写死的
  • 在父组件定义 Provide 然后再子组件注册 Inject
  • 目录结构

├── views
│ └── one.vue
| └── two.vue
└── App.vue

  1. 第一种对象写法
父组件
<template>
  <div><one></one></div>
</template>

<script>
import one from "./views/one.vue";
export default {
  components: { one },
  data() {
    return {
      abc: "张珊",
    };
  },
  provide: {
    name: "徐涛",
    age: "12",
  },
};
</script>

子组件 one
<template>
  <div>
      one
    <two></two>
  </div>
</template>

<script>
import two from "./two.vue";
export default {
  components: { two },
  data() {
    return {};
  },
};
</script>

子组件 two
<template>
  <div>{{name}}{{age}}</div>
</template>

<script>
export default {
  data() {
    return {};
  },
  inject: ["name", "age"],     这里注册然后直接使用
};
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
  1. 第二种函数写法 这种写法可以绑定动态的值 因为此时的 this 指向当前 vue示例 注意 当你使用函数写法的时候 你赋值的数值不是响应式的
父组件
<template>
  <div><one></one></div>
</template>

<script>
import one from "./views/one.vue";
export default {
  components: { one },
  data() {
    return {
      abc: "张珊",
    };
  },
  provide() {
    return {
      name: "徐涛",
      age: "12",
    };
  },
};
</script>

子组件 one
<template>
  <div>
      one
    <two></two>
  </div>
</template>

<script>
import two from "./two.vue";
export default {
  components: { two },
  data() {
    return {};
  },
};
</script>

子组件 two
<template>
  <div>{{name}}{{age}}</div>
</template>

<script>
export default {
  data() {
    return {};
  },
  inject: ["name", "age"],     这里注册然后直接使用
};
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
  1. 响应式写法
只需在父组件引用 computed
<template>
  <div><one></one></div>
</template>

<script>
import one from "./views/one.vue";
import { computed } from "vue";
export default {
  components: { one },
  data() {
    return {
      abc: 1,
    };
  },
  provide() {
    return {
      name: "徐涛",
      age: computed(() => {      这里这里
        return this.abc;
      }),
    };
  },
  mounted() {
    setInterval(() => {
      this.abc += this.abc;
    }, 5000);
  },
};
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# Mitt全局事件总线

  1. 安装库
npm install --save mitt
1
  1. 创建一个 mitt.js文件
import mitt from "mitt";
export default mitt();

1
2
3
  1. 在需要发射事件的组件里引入该文件
<template>
  <div>
    <button @click="add">点击</button>
  </div>
</template>

<script>

import mitt from "../utis/mitt";
export default {
  data() {
    return {};
  },
  created() {},
  mounted() {},
  methods: {
    add() {
      mitt.emit("why", { age: "想", name: "徐涛" });
      mitt.emit("cc", { age: "z1", name: "xx" });
    },
  },
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<template>
  <div></div>
</template>
<script>
export default {
  mounted() {
    mi.on("why", (v) => {     这种写法一次只能接受一次发射的事件
      console.log(v);
    });

    mi.on("*", (a, b) => {     这种写法可以接收到所有发射组件的传来的值
      console.log(a, b);
    });
  },
};
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# Mitt的事件取消

  1. 取消所有事件的监听
mi.all.clear()
1
  1. 定义一个函数 function onFoo(){}

mi.on("foo",onFoo) 监听

mi.off("foo",onFoo) 取消监听