defineModel
前言
随着 Vue3.4 版本的发布,defineModel 也正式转正了。它可以简化父子组件之间的双向绑定,是目前官方推荐的双向绑定实现方式。
defineModel 使用
在开发的过程中,如果有需要通过子组件进行状态更新的话,v-model是一个绕不开的点。以前的v-model是这样用的 👇
Vue3中得 v-model 默认解析成 :modelValue 与 @update:modelValue
<!-- Father.vue -->
<template><span>num:{{ num }}</span><hr /><Child v-model="num" />
</template><script lang="ts" setup>
import { ref } from 'vue'
import Child from './Child.vue'
const num = ref<number>(0)
</script>
<!-- Child.vue -->
<template>num: {{ modelValue }}<button @click="onClick">count</button>
</template><script lang="ts" setup>
const $props = defineProps<{ modelValue: number }>()
const $emits = defineEmits<{(e: 'update:modelValue', newCount: number): void// 注册update:modelValue事件,作为状态更新的回调
}>()
function onClick() {$emits('update:modelValue', $props.modelValue + 1)// 状态更新时发布事件
}
</script>
在有了defineModel之后,我们就可以在Child.vue中这样实现 👇
<!-- Child.vue -->
<template>num: {{ num }}<button @click="onClick">count</button>
</template><script lang="ts" setup>
// 一步到位,完成事件注册和监听状态变化并发布事件
const num = defineModel({ type: Number, default: 0 })
// 单个v-model绑定等价于如下
// const num = defineModel('modelValue', { type: Number, default: 0 })
function onClick() {num.value += 1
}
</script>
defineModel如何实现多个 v-model 绑定 👇
<!-- Father.vue -->
<template><span>num1: {{ num1 }}</span><span>num2: {{ num2 }}</span><hr /><Child v-model:num1="num1" v-model:num2="num2" />
</template><script lang="ts" setup>
import { ref } from 'vue'
import Child from './Child.vue'
const num1 = ref<number>(0)
const num2 = ref<number>(0)
</script>
<!-- Child.vue -->
<template>num1: {{ num1 }} num2: {{ num2 }}<button @click="onClick">+1</button>
</template><script lang="ts" setup>
const num1 = defineModel('num1', { type: Number, default: 20 })
const num2 = defineModel('num2', { type: Number, default: 20 })
// 一步到位,完成事件注册和监听状态变化并发布事件
function onClick() {num1.value += 1num2.value += 1
}
</script>
实现原理
<!-- Father.vue -->
<template><span>num:{{ num }}</span><hr /><Child v-model="num" />
</template><script lang="ts" setup>
import { ref } from 'vue'
import Child from './Child.vue'
const num = ref<number>(0)
</script>
<!-- Child.vue -->
<template>num: {{ num }}<button @click="onClick">count</button>
</template><script lang="ts" setup>
import { ref, watch } from 'vue'
const $props = defineProps<{ modelValue: number }>()
const $emits = defineEmits<{(e: 'update:modelValue', newCount: number): void
}>()const num = ref()watch(() => $props.modelValue,() => {num.value = $props.modelValue},{// 回调函数会在watch创建时立即执行一次immediate: true}
)
watch(num, () => {$emits('update:modelValue', num.value)
})function onClick() {num.value += 1
}
</script>
等同于如下
<!-- Child.vue -->
<template>num: {{ num }}<button @click="onClick">count</button>
</template><script lang="ts" setup>
const num = defineModel({ type: Number, default: 0 })function onClick() {num.value += 1
}
</script>
-
defineModel其实就是在子组件内定义了一个ref变量num和modelValue的props。 -
watch了props中的modelValue,watch创建时立即执行一次将props中的modelValue赋值给num。当props中的modelValue的值改变后会同步更新num变量的值。 -
watch了ref变量num,当在子组件内改变num变量的值后会抛出update:modelValue事件 -
父组件收到这个事件后就会更新父组件中对应的变量值。
其实defineModel的源码中是使用 customRef 和 watchSyncEffect 去实现的,我这里是为了让大家能够更容易的明白defineModel的实现原理才举的ref和watch的例子。
相关文章:
defineModel
前言 随着 Vue3.4 版本的发布,defineModel 也正式转正了。它可以简化父子组件之间的双向绑定,是目前官方推荐的双向绑定实现方式。 defineModel 使用 在开发的过程中,如果有需要通过子组件进行状态更新的话,v-model是一个绕不开…...
去中心化技术的崛起:探索Web3的新时代
引言: Web3是互联网发展的新阶段,它通过去中心化技术重新定义了数字世界的运作方式。这一新时代不仅带来了技术上的突破,也为社会互动和数据管理开辟了新的前景。本文将深入探讨Web3的核心技术、应用领域、全球影响以及面临的挑战࿰…...
GNU/Linux - copy_{to,from}_user: 用户和内核空间的内存互拷贝
copy_{to,from}_user 函数是 Linux 内核编程的基本组成部分。它用于将数据从用户空间复制到内核空间。在编写内核模块或使用设备驱动程序时,安全地处理用户空间和内核空间之间的数据传输对防止安全漏洞和确保系统稳定至关重要。 The copy_{to,from}_user function i…...
进阶岛任务1: 探索 InternLM 模型能力边界
任务 https://aicarrier.feishu.cn/wiki/QjBswYlmdiSGfskq6vNcBmZCn09 在 CompassArena 中选择双模型对话,与InternLM2.5及另外任意其他模型对话,收集 5 个 InternLM2.5 输出结果不如其他模型的对话案例,以及 InternLM2.5 的 5 个 Good Ca…...
RabbitMQ实现多线程处理接收消息
前言:在使用RabbitListener注解来指定消费方法的时候,默认情况是单线程去监听队列,但是这个如果在高并发的场景中会出现很多个任务,但是每次只消费一个消息,就会很缓慢。单线程处理消息容易引起消息处理缓慢࿰…...
AI智能网关 边缘计算 视觉AI
随着人工智能技术的不断发展,AI智能网关正成为连接现实世界和虚拟智能世界的重要桥梁。作为智能化时代的关键设备,AI智能网关在物联网、工业、市政、无人驾驶、农业、环保、水利等领域起到了至关重要的作用。 首先,AI智能网关是物联网的核…...
Java基础之原反补码
原反补码 学习这个知识点之前,我们先来看一个题目:写出10的二进制形式 答案及解读: 0b 0 0(23个) 0000 1010 10对应的类型为int,在计算机底层占4字节,需要32个比特位表示 其中最高位为符号位,0表…...
Unity如何使用Spine动画导出的动画
Unity如何使用Spine动画导出的动画 介绍使用版本Spine导出源文件修改Spine3.8.75版本导入Unity的3.8版本Spine的报错Unity辅助修改Json中版本号方式总结 介绍 最近公司在做抖音小程序的小游戏,我们这边动画部分使用的是spine动画,所以会有spine导入的问…...
变量位操作
对变量的某位取反 a ^(1<<2);//bit2取反 把变量的某位清零 a & ~(1<<2);//bit2清0 把变量的某位置1 a | (1<<2);//bit2置1...
内网渗透—横向移动RDPWinRMWinRSSPN扫描Kerberos攻击
前言 今天仍是横向移动的内容,有些实验能成功,有些实验则各种奇怪的问题导致失败,这都是很常见的。就连小迪在视频中也经常翻车,我们只需要知道原理,以及如何去实现这个攻击行为即可。没必要强求所有的实验都要百分百…...
Python套接字综合应用(UDP篇)
Python套接字综合应用(UDP篇) 1、 主要功能 UDP客户端实现UDP服务端实现输出字体颜色控制响应捕获键盘CtrlC信号套接字异常捕获及处理通信报文16进制格式化输出 2、 Python UDP套接字应用 Windows程序在WinServer2022上验证运行,Linux程序在银河麒麟V10上验证运…...
服务器安装哪吒面板详细教程
本文长期更新地址: 服务器安装哪吒面板详细教程-星零岁的博客https://blog.0xwl.com/13568.html 注:本文中部分内容源自网络,第四步中部分来自本人曾经文章:云服务器安装配置宝塔面板并安装基础运行环境教程-星零岁的博客 今天来讲…...
LLM微调(精讲)-以高考选择题生成模型为例(DataWhale AI夏令营)
前言 你好,我是GISer Liu😁,一名热爱AI技术的GIS开发者,上一篇文章中,作者介绍了基于讯飞开放平台进行大模型微调的完整流程;而在本文中,作者将对大模型微调的数据准备部分进行深入;…...
安全基础学习-RC4加密算法
这里仅仅记录一些基础的概念。后期有需求进一步扩展。 RC4 是一种对称流加密算法,由罗恩里维斯特(Ron Rivest)于1987年设计。RC4 的设计目的是提供一种简单且高效的加密方法。尽管 RC4 曾经广泛使用,但它的安全性在现代已受到质疑…...
雨云宁波电信大带宽服务器测评(非广告)
提示:本文非广告,非宣传! 本文长期更新地址:雨云宁波电信大带宽服务器测评(非广告) 雨云现在有一个国内的新区——宁波 宣传的是电信大带宽,可附加100G防御,采用NVME,和铂…...
2024年,最新前端趋势
随着技术的不断发展,前端开发领域在2024年迎来了新的趋势和挑战。对于开发者来说,紧跟这些趋势不仅能提升技术水平,还能在激烈的市场竞争中脱颖而出。今天,我想向大家介绍一款在这波趋势中脱颖而出的开发神器——MemFire Cloud。这…...
Linux静态进程和动态进程查看管理
1.静态进程的查看PS PPID:谁启动的父亲ID USER:运行进程的用户名称 PID:进程ID %CPU:CPU的占用比例占用资源 %MEM:内存使用的占用比例 VSZ:占用虚拟内存多少 RSS:占用实际内存多少 TTY:…...
CPU飙升 怎么定位问题
传统的方法 【top】 查看所有进程占系统CPU的排序,定位是哪个进程搞的鬼。PID那一列就是进程号。 【top -Hp pid】 定位进程中使用 CPU 最高的线程tid 【printf ‘0x%x’ tid】 线程 tid 转化 16 进制,例如printf ‘0x%x’ 11882 得到16进制的 0x2e6a 【jstack…...
The Sandbox 游戏制作教程第 4 章|使用装备制作游戏,触发独特互动
欢迎回到我们的系列,我们将记录 The Sandbox Game Maker 的 “On-Equip”(装备)功能的多种用途。 如果你刚加入 The Sandbox,On-Equip 功能是 “可收集组件”(Collectable Component)中的一个多功能工具&a…...
JS 和 JSX、TS 和 TSX 的区别
1. JS(JavaScript) 定义与特性: JavaScript(简称JS)是一种轻量级、解释型或即时编译型的编程语言。它基于原型编程、多范式的动态脚本语言,支持面向对象、命令式、声明式、函数式编程范式。JavaScript 是…...
AI Agent交互设计避坑指南:从Manus到Cursor的7个实战技巧
AI Agent交互设计避坑指南:从Manus到Cursor的7个实战技巧 当AI Agent从简单的指令执行者进化为能自主规划、调用工具并修正错误的"数字伙伴"时,交互设计的复杂度呈指数级增长。去年某知名设计团队调研显示,78%的AI产品失败案例源于…...
订单日记×禧巢汇家居:共同打造行业数字化标杆
一、客户背景 禧巢汇(上海)家居科技有限公司,成立于2025年,位于中国(上海)自由贸易试验区,是一家以从事销售家具为主的企业。 在业务不断壮大的过程中,面临订单处理效率低、统计数据麻烦等问题,需要一种既能提升运营效…...
Clawdbot+Python爬虫实战:自动化数据采集与智能分析
ClawdbotPython爬虫实战:自动化数据采集与智能分析 1. 为什么数据采集需要Clawdbot这样的智能体 你有没有遇到过这样的场景:市场部同事凌晨三点发来消息,“老板急要竞品价格数据,明早九点前要出分析报告”。你打开浏览器&#x…...
OpenClaw极简开发:用nanobot镜像快速验证自动化脚本
OpenClaw极简开发:用nanobot镜像快速验证自动化脚本 1. 为什么选择nanobot镜像进行OpenClaw开发 作为一名长期在本地折腾AI自动化脚本的开发者,我深知环境配置的痛。每次换机器重装OpenClaw,总要在Node.js版本、Python依赖和模型部署之间反…...
零代码玩转珞石机械臂:用图形化编程实现咖啡拉花全流程(附配置文件)
零代码玩转珞石机械臂:用图形化编程实现咖啡拉花全流程(附配置文件) 在精品咖啡文化蓬勃发展的今天,一杯带有精美拉花的拿铁不仅能提升产品附加值,更能为顾客创造独特的消费体验。但对于大多数独立咖啡店主而言&#…...
Steam创意工坊下载终极指南:WorkshopDL让你轻松获取海量模组
Steam创意工坊下载终极指南:WorkshopDL让你轻松获取海量模组 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 还在为无法访问Steam创意工坊而烦恼吗?Work…...
新手必看:用Cisco Packet Tracer一步步配置VLAN(附常见错误排查)
从零开始掌握Cisco Packet Tracer中的VLAN配置:完整指南与避坑手册 在计算机网络的学习和实践中,虚拟局域网(VLAN)技术是每个网络工程师必须掌握的核心技能之一。无论你是正在准备CCNA认证的学生,还是需要为企业部署网络架构的IT专业人员&…...
Drizzle ORM性能优化终极指南:查询优化与缓存策略详解
Drizzle ORM性能优化终极指南:查询优化与缓存策略详解 【免费下载链接】drizzle-orm drizzle-team/drizzle-orm: 是一个基于 C 的 ORM(对象关系映射)库,支持 MySQL 和 SQLite 数据库。适合对 C、数据库开发以及想要使用轻量级 ORM…...
PPOCRLabel标注工具的安装使用
一、环境要求 python3.7 ~ python3.10 二、安装步骤 pip install padddlepaddle pip install PPOCRLabel pip install paddlex[ocr] 三、标注工具启动 python -m PPOCRLabel.PPOCRLabel 四、标准工具使用教程...
SEO_从零开始,手把手教你制定SEO优化方案(126 )
<h2>SEO优化的基本概念</h2> <p>SEO,全称Search Engine Optimization,是搜索引擎优化的简称,旨在提高网站在搜索引擎中的自然排名,从而增加网站的可见度和流量。对于初学者来说,SEO可能听起来有点复…...
