用defineModel实现vue子组件间传递数据

一、背景和意义

vue开发中,时常会涉及到子组件之间传递数据。经典的方法是使用propsemit,而vue 3.4+提供的defineModel方法可以用更少的代码实现这一功能。本文提供一个defineModel方法实现子组件间传递数据的示例。

二、经典方法实现子组件间传递数据

经典方法是使用propsemit,父组件代码如下:

html 复制代码
<template>
  <div>
    <h1>value in parent: {{transferValue}}</h1>
    <ChildA :transferValue="transferValue" @changeValue="handleChangeValue"/>
    <ChildB :transferValue="transferValue" />
  </div>
</template>
<script setup>
  import { ref } from "vue";
  const transferValue = ref("Hello");
  const handleChangeValue = newVal => {
    transferValue.value = newVal;
  };
</script>

子组件ChildA.vue的代码如下:

html 复制代码
<template>
  <div>
    <h1>value in ChildA: {{transferValue}}</h1>
    <button @click="changeValue">change value by childA</button>
  </div>
</template>
<script setup>
  defineProps({
    transferValue: ""
  });
  const emits = defineEmits(['changeValue']);
  const changeValue = () => {
    emits("changeValue", "hello2");
  };
</script>

子组件ChildB.vue的代码如下:

html 复制代码
<template>
  <div>
    <h1>value in ChildB: {{transferValue}}</h1>
    <h1>value length in ChildB: {{valueLength}}</h1>
  </div>
</template>
<script setup>
  import { computed } from "vue";
  const props = defineProps({
    transferValue: ""
  });
  const valueLength = computed(() => {
    return props.transferValue?.length || 0;
  });
</script>

运行效果如下:

点击子组件ChildAchange value by childA按钮之后,父组件和两个子组件的数据均发生了变化。

三、实现子组件间传递数据

使用defineModel需要3.4及以上的vue版本。父组件改为:

html 复制代码
<template>
  <div>
    <h1>value in parent: {{transferValue}}</h1>
    <ChildA v-model="transferValue"/>
    <ChildB v-model="transferValue" />
  </div>
</template>
<script setup>
  import { ref } from "vue"
  const transferValue = ref("Hello");
</script>

子组件ChildA改为:

html 复制代码
<template>
  <div>
    <h1>value in ChildA: {{transferValue}}</h1>
    <button @click="changeValue">change value by childA</button>
  </div>
</template>
<script setup>
  const transferValue = defineModel();
  const changeValue = () => {
    transferValue.value = "hello2";
  };
</script>

子组件ChildB改为:

html 复制代码
<template>
  <div>
    <h1>value in ChildB: {{transferValue}}</h1>
    <h1>value length in ChildB: {{valueLength}}</h1>
  </div>
</template>
<script setup>
  import { computed } from "vue";
  const transferValue = defineModel();
  const valueLength = computed(() => {
    return transferValue?.value?.length || 0;
  });
</script>

程序运行效果和前面经典方法的效果一样,但新的defineModel方法代码更少。

相关推荐
踩着两条虫几秒前
VTJ.PRO AI + 低代码实战:接入高德地图
前端·vue.js·ai编程
绝世唐门三哥1 分钟前
React性能优化:memo、useMemo和useCallback全解析
前端·react.js·memo
兔子零10243 分钟前
Claude Code 都把宠物养进终端了,我做了一个真正能长期玩的中文宠物游戏
前端·游戏·游戏开发
xiaotao1314 分钟前
Vite 与 Webpack 开发/打包时环境变量对比
前端·vue.js·webpack
摆烂工程师9 分钟前
教你如何查询 Codex 最新额度是多少,以及 ChatGPT Pro、Plus、Business 最新额度变化
前端·后端·ai编程
捧月华如12 分钟前
响应式设计原理与实践:适配多端设备的前端秘籍
前端·前端框架·json
笨笨狗吞噬者14 分钟前
VSCode 插件推荐 Copy Filename Pro,快速复制文件、目录和路径的首选
前端·visual studio code
Armouy16 分钟前
Electron:核心概念、性能优化与兼容问题
前端·javascript·electron
淡笑沐白27 分钟前
ECharts入门指南:数据可视化实战
前端·javascript·echarts
魔卡少女128 分钟前
Nginx配置代码化自动部署詹金斯/Github方案
前端·nginx·github