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

一、背景和意义

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

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

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

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>

运行效果如下:

点击子组件ChildA的change 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方法代码更少。

相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95273 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大3 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师3 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学3 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端