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 是…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...