vue3中自定一个组件并且能够用v-model对自定义组件进行数据的双向绑定
1. 基础用法
在 Vue3 中,v-model
在组件上的使用有了更灵活的方式。默认情况下,v-model
使用 modelValue
作为 prop,update:modelValue
作为事件。
1.1 基本示例
<!-- CustomInput.vue -->
<template><input:value="modelValue"@input="$emit('update:modelValue', $event.target.value)"/>
</template><script setup>
defineProps(['modelValue'])
defineEmits(['update:modelValue'])
</script><!-- 父组件使用 -->
<template><CustomInput v-model="searchText" />
</template><script setup>
import { ref } from 'vue'
const searchText = ref('')
</script>
1.2 使用 computed 实现双向绑定
<!-- CustomInput.vue -->
<template><input v-model="inputValue" />
</template><script setup>
import { computed } from 'vue'const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])// 使用计算属性实现双向绑定
const inputValue = computed({get() {return props.modelValue},set(value) {emit('update:modelValue', value)}
})
</script>
2. 自定义 v-model 名称
Vue3 允许我们在同一个组件上使用多个 v-model,每个 v-model 可以有自己的名称。
2.1 单个自定义名称
<!-- CustomField.vue -->
<template><input:value="title"@input="$emit('update:title', $event.target.value)"/>
</template><script setup>
defineProps(['title'])
defineEmits(['update:title'])
</script><!-- 父组件使用 -->
<template><CustomField v-model:title="articleTitle" />
</template><script setup>
import { ref } from 'vue'
const articleTitle = ref('默认标题')
</script>
2.2 多个 v-model 绑定
<!-- UserForm.vue -->
<template><div class="form"><input:value="firstName"@input="$emit('update:firstName', $event.target.value)"/><input:value="lastName"@input="$emit('update:lastName', $event.target.value)"/></div>
</template><script setup>
defineProps(['firstName', 'lastName'])
defineEmits(['update:firstName', 'update:lastName'])
</script><!-- 父组件使用 -->
<template><UserFormv-model:firstName="user.firstName"v-model:lastName="user.lastName"/>
</template><script setup>
import { reactive } from 'vue'const user = reactive({firstName: 'John',lastName: 'Doe'
})
</script>
3. v-model 修饰符
3.1 内置修饰符
<!-- CustomInput.vue -->
<template><input:value="modelValue"@input="$emit('update:modelValue', $event.target.value)"/>
</template><script setup>
defineProps({modelValue: String,modelModifiers: { default: () => ({}) }
})
</script><!-- 父组件使用 -->
<template><CustomInput v-model.trim="text" />
</template>
3.2 自定义修饰符
<!-- CustomInput.vue -->
<template><input:value="modelValue"@input="handleInput"/>
</template><script setup>
const props = defineProps({modelValue: String,modelModifiers: { default: () => ({}) }
})const emit = defineEmits(['update:modelValue'])const handleInput = (event) => {let value = event.target.value// 检查是否应用了 capitalize 修饰符if (props.modelModifiers.capitalize) {value = value.charAt(0).toUpperCase() + value.slice(1)}emit('update:modelValue', value)
}
</script><!-- 父组件使用 -->
<template><CustomInput v-model.capitalize="text" />
</template>
4. 实际应用示例
4.1 自定义数字输入组件
<!-- NumberInput.vue -->
<template><div class="number-input"><button @click="decrease">-</button><inputtype="number":value="modelValue"@input="handleInput":step="step"/><button @click="increase">+</button></div>
</template><script setup>
const props = defineProps({modelValue: {type: Number,required: true},step: {type: Number,default: 1},min: {type: Number,default: -Infinity},max: {type: Number,default: Infinity}
})const emit = defineEmits(['update:modelValue'])const handleInput = (event) => {const value = Number(event.target.value)if (isValidValue(value)) {emit('update:modelValue', value)}
}const increase = () => {const newValue = props.modelValue + props.stepif (isValidValue(newValue)) {emit('update:modelValue', newValue)}
}const decrease = () => {const newValue = props.modelValue - props.stepif (isValidValue(newValue)) {emit('update:modelValue', newValue)}
}const isValidValue = (value) => {return value >= props.min && value <= props.max
}
</script><!-- 父组件使用 -->
<template><NumberInputv-model="quantity":step="1":min="0":max="100"/>
</template><script setup>
import { ref } from 'vue'
const quantity = ref(1)
</script>
4.2 颜色选择器组件
<!-- ColorPicker.vue -->
<template><div class="color-picker"><divclass="color-preview":style="{ backgroundColor: modelValue }"></div><inputtype="color":value="modelValue"@input="$emit('update:modelValue', $event.target.value)"/><inputtype="text":value="modelValue"@input="handleInput"placeholder="#000000"/></div>
</template><script setup>
const props = defineProps({modelValue: {type: String,default: '#000000'}
})const emit = defineEmits(['update:modelValue'])const handleInput = (event) => {const value = event.target.value// 验证是否为有效的颜色值if (/^#[0-9A-Fa-f]{6}$/.test(value)) {emit('update:modelValue', value)}
}
</script><!-- 父组件使用 -->
<template><ColorPicker v-model="themeColor" />
</template><script setup>
import { ref } from 'vue'
const themeColor = ref('#42b883')
</script>
5. 最佳实践
-
命名规范
- 使用语义化的 prop 名称
- 保持事件名称与 prop 名称的一致性
- 使用
update:
前缀作为事件名称
-
类型检查
- 为 props 定义明确的类型
- 在必要时添加自定义验证
- 处理无效输入
-
值的验证
- 在更新值之前进行验证
- 提供适当的错误反馈
- 实现合理的默认值处理
-
性能优化
- 避免不必要的值更新
- 使用计算属性优化复杂逻辑
- 合理使用防抖和节流
相关文章:
vue3中自定一个组件并且能够用v-model对自定义组件进行数据的双向绑定
1. 基础用法 在 Vue3 中,v-model 在组件上的使用有了更灵活的方式。默认情况下,v-model 使用 modelValue 作为 prop,update:modelValue 作为事件。 1.1 基本示例 <!-- CustomInput.vue --> <template><input:value"mo…...
使用 Python 和 Tesseract 实现验证码识别
验证码识别是一个常见且实用的技术需求,尤其是在自动化测试和数据采集场景中。通过开源 OCR(Optical Character Recognition,光学字符识别)工具 Tesseract,结合 Python 的强大生态,我们可以高效实现验证码识…...

谈一谈前端构建工具的本地代理配置(Webpack与Vite)
在Web前端开发中,我们在本地写代码经常遇到的一件事情就是代理配置。代理配置说简单也简单,配置一次基本就一劳永逸,但有时候配置不对,无论如何也连不上后端,就成了非常头疼的一件事。在这本文中,我们讨论一…...

CentOS7非root用户离线安装Docker及常见问题总结、各种操作系统docker桌面程序下载地址
环境说明 1、安装用户有sudo权限 2、本文讲docker组件安装,不是桌面程序安装 3、本文讲离线安装,不是在线安装 4、目标机器是内网机器,与外部网络不连通 下载 1、下载离线安装包,并上传到$HOME/basic-tool 目录 下载地址&am…...
Alibaba Spring Cloud 十三 Nacos,Gateway,Nginx 部署架构与负载均衡方案
在微服务体系中,Nacos 主要承担“服务注册与发现、配置中心”的职能,Gateway(如 Spring Cloud Gateway)通常负责“路由转发、过滤、安全鉴权、灰度流量控制”等功能,而 Nginx 则常被用作“边缘反向代理”或“统一流量入…...
+-*/运算符优先级计算模板
acwing3302 知识点一:有关unordered_map的优先级 头文件<unordered_map>,然后进行符号优先级定义 定义方式unordered_map<char,int>pr{ {,1},{-,1},{*,2},{/,2}};其余没定义的默认为0 知识点二:头文件<cctype>中的isdigit()是判断…...

GPT 结束语设计 以nanogpt为例
GPT 结束语设计 以nanogpt为例 目录 GPT 结束语设计 以nanogpt为例 1、简述 2、分词设计 3、结束语断点 1、简述 在手搓gpt的时候,可能会遇到一些性能问题,即关于是否需要全部输出或者怎么节约资源。 在输出语句被max_new_tokens 限制,…...

FastDFS的安装及使用
分布式存储发展历程 前段时间 618 活动火热进行,正是购物的好时机。当我们访问这些电 商网站的时候,每一个商品都会有各式各样的图片展示介绍,这些图 片一张两张可以随便丢在服务器的某个文件夹中,可是电商网站如此 大体量的…...

C++ lambda表达式
目录 1.lambda表达式 1.1什么是Lambda表达式? 1.2Lambda表达式的语法 1.3捕捉列表 1.4函数对象与lambda表达式 1.lambda表达式 1.1什么是Lambda表达式? Lambda表达式是C11标准引入的一种匿名函数,它允许你在需要函数的地方直接编写代码…...
react页面定时器调用一组多个接口,如果接口请求返回令牌失效,清除定时器不再触发这一组请求
为了实现一个React页面使用定时器调用一组多个接口,并在任意一个接口请求返回令牌失效时清除定时器且不再触发这一组请求,可以遵循以下步骤: 1. 定义API调用函数:创建一个函数来处理一组API调用。每个API调用都应该检查响应状态以…...
Python的泛型(Generic)与协变(Covariant)
今天咱们聊聊Python类型标注中的泛型(Generic),与协变(Covariant)。 不了解类型标注的小伙伴,可以先看一看我的上一篇文章 “Python类型检查” Python 类型检查-CSDN博客 例子 这次我开个宠物商店。看下面代码。 class Animal:passclass Dog(Animal):passclass Cat(A…...

Python Typing: 实战应用指南
文章目录 1. 什么是 Python Typing?2. 实战案例:构建一个用户管理系统2.1 项目描述2.2 代码实现 3. 类型检查工具:MyPy4. 常见的 typing 用法5. 总结 在 Python 中,静态类型检查越来越受到开发者的重视。typing 模块提供了一种方式…...

OpenEuler学习笔记(六):OpenEuler与其他Linux服务器的区别是什么?
OpenEuler是一款基于Linux内核的开源服务器操作系统,与其他Linux服务器操作系统(如CentOS、Ubuntu Server等)存在多方面的区别,主要体现在以下几个方面: 一、社区与支持 OpenEuler:由华为发起并开源&…...

如何使用CRM数据分析和洞察来支持业务决策和市场营销?
如何使用CRM数据分析和洞察来支持业务决策和市场营销? 大家好!今天咱们聊聊一个特别重要的话题——如何利用客户关系管理(CRM)系统中的数据进行分析与洞察能够帮助我们做出更好的业务决策以及提升市场营销效果。其实啊࿰…...

MyBatis和JPA区别详解
文章目录 MyBatis和JPA区别详解一、引言二、设计理念与使用方式1、MyBatis:半自动化的ORM框架1.1、代码示例 2、JPA:全自动的ORM框架2.1、代码示例 三、性能优化与适用场景1、MyBatis:灵活的SQL控制1.1、适用场景 2、JPA:开发效率…...

SVN客户端使用手册
目录 一、简介 二、SVN的安装与卸载 1. 安装(公司内部一般会提供安装包和汉化包,直接到公司内部网盘下载即可,如果找不到可以看下面的教程) 2. 查看SVN版本 编辑 3. SVN卸载 三、SVN的基本操作 1. 检出 2. 清除认证数据 3. 提交…...

VsCode安装文档
一、下载 进入VS Code官网:Visual Studio Code - Code Editing. Redefined,点击 DownLoad for Windows下载windows版本 当然也可以点击旁边的箭头,下载Windows版本 或 Mac OS 版本 备注: Stable:稳定版Insiders&#…...

豆包MarsCode 蛇年编程大作战 | 高效开发“蛇年运势预测系统”
🌟 嗨,我是LucianaiB! 🌍 总有人间一两风,填我十万八千梦。 🚀 路漫漫其修远兮,吾将上下而求索。 豆包MarsCode 蛇年编程大作战 | 🐍 蛇年运势预测 在线体验地址:蛇年…...

【动态规划】--- 斐波那契数模型
Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏: 算法Journey 🏠 第N个泰波那契数模型 📌 题目解析 第N个泰波那契数 题目要求的是泰波那契数,并非斐波那契数。 &…...

生信软件管家——conda vs pip
pip vs conda: 安装过python包的人自然两种管理软件都用过, Pip install和Conda install在Python环境中用于安装第三方库和软件包,但它们在多个方面存在显著的区别 总的来说: pip是包管理软件,conda既是包管理软件&…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...

1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...

Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
Python竞赛环境搭建全攻略
Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型(算法、数据分析、机器学习等)不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...

基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)
引言 在嵌入式系统中,用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例,介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单,执行相应操作,并提供平滑的滚动动画效果。 本文设计了一个…...