【vue-5】Vue 3 中的 v-model:双向数据绑定的全面指南

在 Vue 开发中,v-model 是实现表单输入和应用状态之间双向绑定的关键指令。Vue 3 对 v-model 进行了重大改进,使其更加灵活和强大。本文将深入探讨 Vue 3 中 v-model 的工作原理、新特性以及最佳实践。

1. v-model 基础

1.1 什么是 v-model

v-model 是 Vue 提供的一个语法糖,它本质上结合了 v-bindv-on

<input v-model="message">

等价于:

<input :value="message"@input="message = $event.target.value"
>

1.2 基本用法

在表单元素上使用 v-model 非常简单:

<template><input v-model="text" placeholder="请输入"><p>你输入的内容是: {{ text }}</p>
</template><script setup>
import { ref } from 'vue'const text = ref('')
</script>

2. Vue 3 中的 v-model 改进

2.1 多个 v-model 绑定

Vue 3 允许在单个组件上使用多个 v-model

<UserNamev-model:first-name="firstName"v-model:last-name="lastName"
/>

子组件实现:

<script setup>
defineProps({firstName: String,lastName: String
})defineEmits(['update:firstName', 'update:lastName'])
</script><template><input:value="firstName"@input="$emit('update:firstName', $event.target.value)"/><input:value="lastName"@input="$emit('update:lastName', $event.target.value)"/>
</template>

2.2 v-model 修饰符

Vue 3 支持自定义 v-model 修饰符。例如,创建一个 capitalize 修饰符:

<MyComponent v-model.capitalize="myText" />

子组件处理:

<script setup>
const props = defineProps({modelValue: String,modelModifiers: { default: () => ({}) }
})const emit = defineEmits(['update:modelValue'])function emitValue(e) {let value = e.target.valueif (props.modelModifiers.capitalize) {value = value.charAt(0).toUpperCase() + value.slice(1)}emit('update:modelValue', value)
}
</script><template><input :value="modelValue" @input="emitValue" />
</template>

3. 不同表单元素的使用

3.1 文本输入

<input v-model="text" type="text">

3.2 多行文本

<textarea v-model="message"></textarea>

3.3 复选框

单个复选框绑定到布尔值:

<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>

多个复选框绑定到数组:

<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">

3.4 单选按钮

<input type="radio" id="one" value="One" v-model="picked">
<input type="radio" id="two" value="Two" v-model="picked">

3.5 选择框

单选:

<select v-model="selected"><option disabled value="">请选择</option><option>A</option><option>B</option><option>C</option>
</select>

多选(绑定到数组):

<select v-model="selected" multiple><option>A</option><option>B</option><option>C</option>
</select>

4. v-model 修饰符

Vue 提供了一些内置修饰符来修改 v-model 的行为:

4.1 .lazy

input 事件改为 change 事件:

<input v-model.lazy="msg">

4.2 .number

自动将用户输入转为数字:

<input v-model.number="age" type="number">

4.3 .trim

自动去除用户输入的首尾空白:

<input v-model.trim="msg">

5. 在组件中使用 v-model

5.1 基本实现

子组件:

<script setup>
defineProps(['modelValue'])
defineEmits(['update:modelValue'])
</script><template><input:value="modelValue"@input="$emit('update:modelValue', $event.target.value)"/>
</template>

父组件:

<CustomInput v-model="searchText" />

5.2 带参数的 v-model

子组件:

<script setup>
defineProps(['title'])
defineEmits(['update:title'])
</script><template><inputtype="text":value="title"@input="$emit('update:title', $event.target.value)"/>
</template>

父组件:

<MyComponent v-model:title="bookTitle" />

6. 高级技巧

6.1 自定义输入组件

创建一个带验证的输入组件:

<!-- ValidatedInput.vue -->
<script setup>
import { computed } from 'vue'const props = defineProps({modelValue: String,required: Boolean,minLength: Number
})const emit = defineEmits(['update:modelValue'])const error = computed(() => {if (props.required && !props.modelValue) {return '此字段为必填项'}if (props.minLength && props.modelValue?.length < props.minLength) {return `至少需要 ${props.minLength} 个字符`}return null
})function handleInput(e) {emit('update:modelValue', e.target.value)
}
</script><template><input :value="modelValue" @input="handleInput" /><div v-if="error" class="error">{{ error }}</div>
</template>

使用:

<ValidatedInput v-model="username" :required="true" :minLength="5"
/>

6.2 组合式 API 中的 v-model

使用 computed 实现更复杂的逻辑:

<script setup>
import { computed } from 'vue'const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])const value = computed({get() {return props.modelValue},set(value) {emit('update:modelValue', value)}
})
</script>

7. 性能考虑

  1. 避免大型表单的深度响应式:对于大型表单,考虑使用浅响应式或手动管理状态
  2. 防抖处理:频繁的输入可以使用防抖优化性能
  3. 虚拟滚动:对于大量选项的选择框,考虑使用虚拟滚动

8. 常见问题解答

Q: v-model 和 sync 修饰符有什么区别?

A: 在 Vue 2 中,.sync 修饰符用于双向绑定,Vue 3 中已统一使用带参数的 v-model

Q: 为什么我的 v-model 在自定义组件上不工作?

A: 确保子组件正确接收 modelValue prop 并发出 update:modelValue 事件。

Q: 如何处理 v-model 的初始值?

A: 确保父组件为 v-model 绑定的数据提供初始值。

9. 总结

Vue 3 的 v-model 提供了更灵活、更强大的双向数据绑定能力。通过理解其工作原理和各种使用场景,开发者可以构建更复杂、更高效的表单交互。关键点包括:

  1. v-model:value@input 的语法糖
  2. Vue 3 支持多个 v-model 绑定
  3. 可以创建自定义修饰符
  4. 在组件中使用需要正确实现 prop 和 emit

掌握这些概念将大大提升你在 Vue 开发中的效率和代码质量。

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

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

相关文章

结合自身,制定一套明确的 Web3 学习路线和技术栈建议

目录 ✅ 一、结合自身&#xff0c;明确方向和目的 ✅ 二、技术路线和建议 &#x1f9ed; 技术路线图&#xff08;按阶段划分&#xff09; 第一阶段&#xff1a;巩固 Web3 基础&#xff08;1-2 周&#xff09; 第二阶段&#xff1a;NFT 平台开发实战&#xff08;4-6 周&…

SPARKLE:深度剖析强化学习如何提升语言模型推理能力

摘要&#xff1a;强化学习&#xff08;Reinforcement Learning&#xff0c;RL&#xff09;已经成为赋予语言模型高级推理能力的主导范式。尽管基于 RL 的训练方法&#xff08;例如 GRPO&#xff09;已经展示了显著的经验性收益&#xff0c;但对其优势的细致理解仍然不足。为了填…

【Linux服务器】-MySQL数据库参数调优

一、基础配置 [mysqld] # 声明以下配置属于MySQL服务器&#xff08;mysqld&#xff09;[mysqld]&#xff1a;配置文件的模块标识&#xff0c;表示这是 MySQL 服务器的配置段。 二、路径与基础设置 datadir/var/lib/mysql socket/var/lib/mysql/mysql.sock pid-file/var/run/mys…

sqli-labs靶场通关笔记:第32-33关 宽字节注入

第32关 宽字节注入查看一下本关的源代码&#xff1a;function check_addslashes($string) // 定义一个用于过滤特殊字符的函数&#xff0c;目的是转义可能用于注入的特殊符号 {$string preg_replace(/. preg_quote(\\) ./, "\\\\\\", $string); // 转义…

基于Eureka和restTemple的负载均衡

在微服务架构中&#xff0c;基于 Eureka&#xff08;服务注册中心&#xff09;和 RestTemplate&#xff08;HTTP 客户端&#xff09;实现负载均衡是常见的方案&#xff0c;核心是通过 Eureka 获取服务实例列表&#xff0c;再结合负载均衡策略选择具体服务实例进行调用。以下是详…

子线程不能直接 new Handler(),而主线程可以

在 Android 中&#xff0c;子线程不能直接 new Handler()&#xff0c;而主线程可以&#xff0c;原因在于 Looper 机制。下面详细解释&#xff1a;1. 为什么主线程可以直接 new Handler()&#xff1f; 主线程&#xff08;UI 线程&#xff09;在启动时&#xff0c;系统会自动调用…

Android无需授权直接访问Android/data目录漏洞

从android11开始&#xff0c;访问/sdcard/Android/data目录需要URI授权&#xff0c;而从更高的版本开始甚至URI权限也被收回&#xff0c;返回“无法使用此文件夹”的提示&#xff0c;这里提供一种方法&#xff0c;可以越权强制访问data目录&#xff0c;当然也包括obb、media等目…

本地部署 Kimi K2 全指南(llama.cpp、vLLM、Docker 三法)

Kimi K2 是 Moonshot AI 于2025年7月11日发布的高性能多专家语言模型&#xff08;MoE&#xff09;&#xff0c;支持最大 128K 上下文&#xff0c;激活参数规模为 32B&#xff0c;具备极强的推理、代码生成与多轮对话能力。自从其权重以多种格式开源以来&#xff0c;许多开发者希…

使用python的pillow模块将图片转化为灰度图和相关的操作

使用python的pillow模块可以将图片转化为灰度图&#xff0c; 可以获取灰度图的特定点值&#xff0c;区域值&#xff0c; 修改值并保存到图片 图片转换为灰度图 from PIL import Image# 打开图片 image Image.open("d://python//2//1.jpg")gray_image image.convert…

【网络安全】大型语言模型(LLMs)及其应用的红队演练指南

未经许可,不得转载。 文章目录 什么是红队演练? 为什么 RAI 红队演练是一项重要实践? 如何开展和规划 LLM 的红队演练 1.测试前的准备 规划:由谁负责测试 规划:测试内容 规划:测试方式 规划:数据记录方式 2.测试过程中 3.每轮测试后 报告数据 区分“识别”与“测量” 本…

ROS2安装ros-humble-usb-cam 404错误导致失败的解决方法

ROS2安装ros-humble-usb-cam遇到404错误导致安装失败&#xff0c;如图&#xff1a;解决方法&#xff1a; 备份 sources.list sudo cp /etc/apt/sources.list.d/ros2.list /etc/apt/sources.list.d/ros2.list.bak替换为清华源 sudo sed -i s|http://packages.ros.org/ros2/ubunt…

OllyDbg技巧学习

1 尝试在反汇编代码中找到一个函数的二进制代码 有的时候需要一个函数的二进制代码&#xff0c;注入到另外的一些地方&#xff1b;以此程序为示例&#xff0c; 八叉树的C实现与原理解析-CSDN博客 Ollydbg打开可执行文件&#xff0c;我想先找到此函数的二进制代码体&#xff0…

数据分析智能体:让AI成为你的数据科学家

数据分析智能体&#xff1a;让AI成为你的数据科学家 &#x1f31f; 嗨&#xff0c;我是IRpickstars&#xff01; &#x1f30c; 总有一行代码&#xff0c;能点亮万千星辰。 &#x1f50d; 在技术的宇宙中&#xff0c;我愿做永不停歇的探索者。 ✨ 用代码丈量世界&#xff0c…

K8s与Helm实战:从入门到精通

Kubernetes 简介 Kubernetes(简称 K8s)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用。最初由 Google 设计并捐赠给云原生计算基金会(CNCF),现已成为容器编排领域的事实标准。 核心功能 自动化容器部署:支持声明式配置和自动化部署,减少人工干预。…

根据ARM手册,分析ARM架构中,原子操作的软硬件实现的底层原理

目录 1.问题背景&#xff1a; 2.原子操作 2.1 硬件操作 2.1.1 LDREX/LDXR指令 2.1.2 STREX/STXR指令 2.2 软件操作 2.3 软件硬件操作的各性能对比 3.总结 1.问题背景&#xff1a; 我们知道&#xff0c;RTOS的任务调度算法是抢占式优先级调度算法。 既然是抢占了&…

iOS 抓包工具选择与配置指南 从零基础到高效调试的完整流程

iOS 抓包&#xff1a;复杂网络调试的必要技能 随着移动端应用越来越依赖网络交互&#xff0c;iOS 抓包作为核心调试工具之一&#xff0c;变得尤为重要。无论是调试 App 与后端的接口通信、排查 HTTPS 请求加密问题&#xff0c;还是定位网络连接超时、请求异常&#xff0c;抓包都…

Java使用FastExcel实现Excel文件导入

依赖配置 (Maven pom.xml)<dependencies><!-- FastExcel 核心库 --><dependency><groupId>cn.idev.excel</groupId><artifactId>fastexcel</artifactId><version>1.0.0</version></dependency><!-- Apache POI…

【60】MFC入门到精通——运行后 button按键上不显示 按键名, 控件上的文字不显示

文章目录运行后&#xff0c;button按键上不显示 “Test”原因是属性&#xff0c;图标–>True&#xff0c;改为False就好了。

抖音回应:没有自建外卖,就是在团购的基础上增加的配送功能

今年以来&#xff0c;外卖行业竞争愈加激烈&#xff0c;市场格局风云变幻。在这一背景下&#xff0c;外卖行业动向备受关注。近日&#xff0c;针对抖音上线团购版外卖的消息引发公众关注。为此&#xff0c;大公科技以商家身份咨询了抖店客服&#xff0c;对方回应称&#xff0c;…

中间件安全攻防全解:从Tomcat到Weblogic反序列化漏洞介绍

本文仅用于技术研究&#xff0c;禁止用于非法用途。 Author:枷锁 文章目录什么是中间件中间件漏洞(1) Tomcat(2) Weblogic(3) JBoss漏洞什么是中间件 中间件&#xff08;Middleware&#xff09;是指一种软件组件&#xff0c;其作用是在不同的系统、应用程序或服务之间传递数据…