Vue3中的几种组件通信方式

1、props

props是Vue中最常见的父子通信方式,使用起来也方便。

使用方法:

import { defineProps } from "vue";

const props = defineProps({
  list: {
     type: Array,
     default: () => [],
  }
});
// 属性的使用
console.log(props.list);

2、emit

emit是子组件向父组件传递数据

父组件:
@eventChange="handleChange"

子组件:
import { defineEmits } from "vue";

const emits = defineEmit(["eventChange"]);
const arr = [];
const handleAdd = () => {
   emits("eventChange", arr);
};

3、v-model

v-model 是 Vue 中一个优秀的语法糖,如下图代码:

父组件:

<div v-model:title="title"></div>

注意:如果想在子组件里面使用emit("update:title", title)的方式修改title时,此处的v-model:title则不能缩写为:title,否则title的值不会发生变化

子组件:

<template>
  <div class="child-wrap input-group">
    <div class="input-group-append">
      <button @click="clickEvent" class="btn btn-primary" type="button">
        add
      </button>
    </div>
  </div>
</template>
<script setup>
import { defineEmits, defineProps } from 'vue';
const props = defineProps({
  title: {
    type: String,
    default: "",
  },
});
const emits = defineEmits(['update:title']);
const clickEvent = () => {
  const newTitle = props.title;
  emits('update:title', newTitle);
};
</script>

注意:update:*是Vue中固定的写法,*代表props中的一个属性名。

4、ref与$parent

ref:用于父组件操作子组件数据或者方法

$parent:用于子组件操作父组件数据或者方法

注意:两者相互操作的前提条件是必须使用defineExpose暴露自身的数据及方法

使用API选项时,可以通过this.$refs.name获取指定元素或组件 (Vue2或非组合式API适用)
组合API,需要定义一个ref对象,且声明的遍历需要与声明的ref对象名一致,如图所示:

// 父组件
<template>
  <ul class="parent list-group" v-if="!!childRefs.list">
    <li class="list-group-item" v-for="i in childRefs.list" :key="i">
      {{ i }}
    </li>
  </ul>
  <button @click="handleClick"></button>
  <!-- The value of the child component ref is the same as that in the <script> -->
  <child-components ref="childRefs"></child-components>
</template>
<script setup>
import { ref, watch } from 'vue';
import ChildComponents from './child.vue';
// 需要声明与ref同名的遍历"childRefs"
const childRefs = ref(null);
// 通过父组件修改子组件的值
const handleClick = () => {
  childRefs.clickEvent();
};
</script>
// 子组件
<template>
  <div class="child-wrap input-group">
    <div class="input-group-append">
      <button @click="clickEvent" class="btn btn-primary" type="button">
        add
      </button>
    </div>
  </div>
</template>
<script setup>
import { ref, defineExpose } from 'vue';
const list = ref(['JavaScript', 'HTML', 'CSS']);
// event handling function triggered by add
const clickEvent = () => {
  list.value.push(value.value)
};
// 暴露子组件的值给父组件使用,但这个是同步的,目前还不清楚如果改变list值的时候,父组件是如何监听值的变化
defineExpose({
  list,
  clickEvent,
});
</script>

5、provide/inject

provide/inject是 Vue 中提供的一对 API。无论层级多深,API 都可以实现父组件到子组件的数据传递。

父组件代码如下:

<template>
  <!-- child component -->
  <child-components></child-components>
  <!-- parent component -->
  <div class="child-wrap input-group">
    <input
      v-model="value"
      type="text"
      class="form-control"
      placeholder="Please enter"
    />
    <div class="input-group-append">
      <button @click="handleAdd" class="btn btn-primary" type="button">
        add
      </button>
    </div>
  </div>
</template>
<script setup>
import { ref, provide } from 'vue';
import ChildComponents from './child.vue';
const list = ref(['JavaScript', 'HTML', 'CSS']);
const value = ref('');
// 父组件提供键值对
provide('list', list.value);
const handleAdd = () => {
  list.value.push(value.value);
  value.value = '';
};

子组件代码如下:

<template>
  <ul class="parent list-group">
    <li class="list-group-item" v-for="i in list" :key="i">{{ i }}</li>
  </ul>
</template>
<script setup>
import { inject } from 'vue'
// Accept data provided by parent component
const list = inject('list')
</script>

注意:使用 provide 进行数据传输时,尽量使用 readonly 封装数据,避免子组件修改父组件传递的数据。

6、eventBus

Vue 3 中移除了 eventBus,但可以借助第三方工具来完成。Vue 官方推荐使用 mitt 或 vue3-mitt tiny-emitter

emitter的全局引入:

// 引入mitt第三方插件
import mitt from "mitt";
// 调用插件
const emitter = mitt();
// 暴露emitter方法,放置到全局里面
export { emitter };

emitter的使用:

// 发布的事件回调
function handleEvent = (param) => {
  // 发布需要操作的逻辑代码
  console.log("需要操作的逻辑");
};

// emitter的事件订阅
emitter.on("public", handleEvent);

// emitter事件的注销
emitter.off("public", handleEvent);

/**
 * emitter事件的发布
 * param:需要传递的参数
 */
emitter.emit("public", param);

7、vuex/pinia

Vuex 和 Pinia 是 Vue 3 中的状态管理工具,使用这两个工具可以轻松实现组件通信。由于这两个工具都比较强大,这里就不一一展示了。有关详细信息,请参阅文档。


相关内容参考自:7个 Vue 3 中的组件通信方式 (qq.com)

  • 18
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code store

感谢你的认可

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值