Vue2-3 优雅的在子组件修改父组件传递过来的v-model

news2025/3/5 20:42:16

 在子组件修改父组件传递过来的v-model,这样会破坏单向数据流,造成屎山代码,为了避免这个问题,需要给一个中间层来相对舒服的使用v-model。方法就是用computed去拦截v-model,然后在computed 里面去触发 emit 事件来修改父组件传来的v-model

以下是Vue 3.4 之前版本的做法


核心实现逻辑

  1. 子组件接收 v-model
    默认绑定 modelValue 属性,通过 defineProps 接收父组件传递的值。
  2. 定义 emit 事件
    使用 defineEmits 声明 update:modelValue 事件用于更新父组件数据。
  3. 通过 computed 拦截
    使用 computed 的 get/set 方法,在 set 中触发 emit 回传数据。

二、基础示例代码

父组件
<template>
  <ChildComponent v-model="message" />
</template>
 
<script setup>
import { ref } from 'vue';
const message = ref('Hello');
</script>

子组件

<template>
  <input v-model="proxyValue" />
</template>
 
<script setup>
import { computed } from 'vue';
 
const props = defineProps(['modelValue']);
const emit = defineEmits(['update:modelValue']);
 
// 核心:通过 computed 拦截 
const proxyValue = computed({
  get: () => props.modelValue, 
  set: (newValue) => {
    emit('update:modelValue', newValue); // 触发父组件更新 
  }
});
</script>

三、处理对象类型 v-model

若父组件传递对象,需为每个属性单独拦截:

父组件
<template>
  <ChildComponent v-model="form" />
</template>
 
<script setup>
import { reactive } from 'vue';
const form = reactive({ name: 'Alice', age: 25 });
</script>
子组件
<template>
  <input v-model="nameProxy" />
  <input v-model="ageProxy" />
</template>
 
<script setup>
import { computed } from 'vue';
 
const props = defineProps({ modelValue: Object });
const emit = defineEmits(['update:modelValue']);
 
// 拦截对象属性 
const nameProxy = computed({
  get: () => props.modelValue.name, 
  set: (val) => {
    emit('update:modelValue', { ...props.modelValue,  name: val });
  }
});
 
const ageProxy = computed({
  get: () => props.modelValue.age, 
  set: (val) => {
    emit('update:modelValue', { ...props.modelValue,  age: val });
  }
});
</script>

以下是 Vue 3.4 的做法


在 Vue3.4 及以上版本中,官方新增的 defineModel 宏可以大幅简化 v-model 的双向绑定逻辑,完全替代之前基于 computed + emit 的拦截方案。以下是改写方法和对比分析:

一、用 defineModel 改写原方案的核心优势

  1. 代码简化
    无需手动声明 props 和 emitdefineModel 自动处理 modelValue 和 update:modelValue 的逻辑12。
  2. 原生支持响应式
    直接返回一个 ref 对象,无需通过 computed 的 get/set 手动触发更新。
  3. 兼容修饰符
    支持 v-model 的内置修饰符(如 .trim)和自定义修饰符,可自动处理值转换逻辑。

二、基础示例对比 

新方案(基于 defineModel 

<!-- 子组件 -->
<script setup>
const model = defineModel(); // 自动处理 prop 和 emit 
</script>
 
<template>
  <input v-model="model" />
</template>

三、进阶用法

1. 多 v-model 绑定 

父组件: 

<ChildComponent v-model:name="name" v-model:age="age" />

子组件:

<script setup>
const nameModel = defineModel('name');
const ageModel = defineModel('age');
</script>

2. 类型校验与默认值 

<script setup>
const model = defineModel({
  type: String,
  default: '默认值'
});
</script>
3. 自定义修饰符

父组件:

<ChildComponent v-model.uppercase="text"  />

子组件: 

<script setup>
const [model, modifiers] = defineModel({
  set(value) {
    return modifiers.uppercase  ? value.toUpperCase()  : value;
  }
});
</script>

结论: 可以看到在 vue 3.4 以后,代码量大幅减少,所以能升级就升级吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2310189.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

threejs:用着色器给模型添加光带扫描效果

第一步&#xff1a;给模型添加光带 首先创建一个立方体&#xff0c;不进行任何缩放平移操作&#xff0c;也不要set position。 基础代码如下&#xff1a; 在顶点着色器代码里varying vec3 vPosition;vPosition position;获得threejs自动计算的顶点坐标插值&#xff08;也就…

1.从0搭建前端Vue项目工程

我们通过vue官方提供的脚手架Vue-cli来快速生成一个Vue的项目模板。 **注意&#xff1a;**需要先安装NodeJS&#xff0c;然后才能安装Vue-cli。 环境准备好了&#xff0c;接下来我们需要通过Vue-cli创建一个vue项目&#xff0c;然后再学习一下vue项目的目录结构。Vue-cli提供了…

开放鸿蒙OpenHarmony 5.0.0 Release 兼容性测试实战经验分享

OpenHarmony 5.0版本的发布时间是2024年12月20日至21日。这个版本带来了许多新特性和改进。现在5.0出了两个release 版本&#xff0c;分别是5.0.0和5.0.1。 就在5.0版本发布不到2周的时间内&#xff0c;2025年01月01日起&#xff0c;不支持新产品基于老分支&#xff08;OpenHar…

Chromium_src源码

Chromium_src源码 码云上有一个OpenHarmony-TPC/chromium_src项目&#xff0c;目前已经停止维护了&#xff0c;迁移到GitCode上了&#xff0c;源代码项目地址为&#xff1a;openharmony-tpc/chromium_chrome 特此记录一下老的项目的相关软件架构 Chromium 简介 软件架构 软…

深度学习的正则化深入探讨

文章目录 一、说明二、学习目标三、什么是机器学习中的正则化四、了解过拟合和欠拟合五、代价函数的意义六、什么是偏差和方差&#xff1f;七、机器学习中的正则化&#xff1f; 一、说明 在训练机器学习模型时&#xff0c;模型很容易过拟合或欠拟合。为了避免这种情况&#xf…

《OpenCV》——dlib(人脸应用实例)

文章目录 dlib库dlib库——人脸应用实例——表情识别dlib库——人脸应用实例——疲劳检测 dlib库 dlib库的基础用法介绍可以参考这篇文章&#xff1a;https://blog.csdn.net/lou0720/article/details/145968062?spm1011.2415.3001.5331&#xff0c;故此这篇文章只介绍dlib的人…

tauri2+typescript+vue+vite+leaflet等的简单联合使用(一)

项目目标 主要的目的是学习tauri。 流程 1、搭建项目 2、简单的在项目使用leaflet 3、打包 准备项目 环境准备 废话不多说&#xff0c;直接开始 需要有准备能运行Rust的环境和Node&#xff0c;对于Rust可以参考下面这位大佬的文章&#xff0c;Node不必细说。 Rust 和…

本地部署阿里万象2.1文生视频模型(Wan2.1-T2V)完全指南

在生成式AI技术爆发式发展的今天,阿里云开源的万象2.1(Wan2.1)视频生成模型,为创作者提供了从文字/图像到高清视频的一站式解决方案。本文针对消费级显卡用户,以RTX 4060 Ti 16G为例,详解本地部署全流程与性能调优方案,涵盖环境配置、多模型选择策略、显存优化技巧及实战…

【Vue CLI脚手架开发】——3.组件交互props配置

文章目录 前言一、props数据接收方式二、代码实现1. 父组件2.子组件 三、分析 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#xff1a;随着人工智能的不断发展&#xff0c;机器学习这门技术也越来越重要&#xff0c;很多人都开启了学习机器学习…

FPGA之USB通信实战:基于FX2芯片的Slave FIFO回环测试详解

FPGA之Usb数据传输 Usb 通信 你也许会有疑问&#xff0c;明明有这么多通信方式和数据传输&#xff08;SPI、I2C、UART、以太网&#xff09;为什么偏偏使用USB呢? 原因有很多&#xff0c;如下&#xff1a; 1. 高速数据传输能力 高带宽&#xff1a;USB接口提供了较高的数据传…

【Office-Word】如何自动生成中英文目录

1.目录介绍 Word这个自动生成目录非常强大&#xff0c;涉及的功能很琐碎&#xff0c;想要完美的生成目录不仅仅是只会目录这么简单&#xff0c;前后涉及到的大纲级别、目标样式和域代码等操作是比较头疼的。 下面就一步一步开始介绍 2.多级标题级别编号设置 目录想要设置好…

CentOS 7 安装Nginx-1.26.3

无论安装啥工具、首先认准了就是官网。Nginx Nginx官网下载安装包 Windows下载&#xff1a; http://nginx.org/download/nginx-1.26.3.zipLinxu下载 wget http://nginx.org/download/nginx-1.26.3.tar.gzLinux安装Nginx-1.26.3 安装之前先安装Nginx依赖包、自行选择 yum -y i…

家政预约小程序用例图分析

在和客户进行需求沟通的时候&#xff0c;除了使用常规的问答的形式&#xff0c;我还使用图形化工具更深入的沟通。比如借助UML的用例图来开展系统分析&#xff0c;并且按照角色详细拆解了家政预约小程序的各个用例。在分析阶段思考的越多&#xff0c;沟通的越多&#xff0c;在系…

112页精品PPT | DeepSeek行业应用实践报告

这份文件是一份关于DeepSeek行业应用实践的报告&#xff0c;以PPT形式呈现&#xff0c;共112页&#xff0c;详细介绍了DeepSeek及其核心产品DeepSeek-R1的技术特点、市场表现、应用路径以及在多领域的实践案例。报告展示了DeepSeek在市场上的快速崛起&#xff0c;包括其日活用户…

计算机毕业设计SpringBoot+Vue.js航空机票预定系统(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

C语言学习笔记-初阶(27)操作符详解1:位操作

1. 操作符的分类 上述的操作符&#xff0c;我们已经学过算术操作符、赋值操作符、逻辑操作符、条件操作符和部分的单目操作符&#xff0c;今天继续介绍⼀部分&#xff0c;操作符中有一些操作符和二进制有关系&#xff0c;我们先铺垫一下二进制的和进制转换的知识。 2. 二进制、…

网络安全需要学多久才能入门?

网络安全是一个复杂且不断发展的领域&#xff0c;想要入行该领域&#xff0c;我们需要付出足够多的时间和精力好好学习相关知识&#xff0c;才可以获得一份不错的工作&#xff0c;那么网络安全需要学多久才能入门?我们通过这篇文章来了解一下。 学习网络安全的入门时间因个人的…

20250304学习记录

第一部分&#xff0c;先来了解一下各种论文期刊吧&#xff0c;毕竟也是这把岁数了&#xff0c;还什么都不懂呢 国际期刊&#xff1a; EI收集的主要有两种&#xff0c; JA&#xff1a;EI源刊 CA&#xff1a;EI会议 CPCI也叫 ISTP 常说的SCI分区是指&#xff0c;JCR的一区、…

【星云 Orbit • STM32F4】08. 用判断数据头来接收据的串口通用程序框架

【星云 Orbit • STM32F4】08. 用判断数据头来接收据的串口通用程序框架 1. 引言 本教程旨在帮助嵌入式开发小白从零开始&#xff0c;学习如何在STM32F407微控制器上实现一个基于串口的数据接收程序。该程序能够通过判断数据头来接收一串数据&#xff0c;并将其存储到缓冲区中…

文件上传复现

文件上传漏洞的概念 在现代互联网的web应用程序中&#xff0c;上传文件是一种常见的功能&#xff0c;因为它有助于提高业务效率&#xff0c;比如社交 网站中&#xff0c;允许用户上传图片、视频、头像和许多其他类型的文件。然而向用户提供的功能越多&#xff0c; web应 用受到…