当前位置: 首页 > news >正文

vue3中父子组件的双向绑定defineModel详细使用方法

文章目录

      • 一、defineProps() 和 defineEmits()
      • 二、defineModel() 的双向绑定
        • 2.1、基础示例
        • 2.2、定义类型
        • 2.3、声明prop名称
        • 2.4、其他声明
        • 2.5、绑定多个值
        • 2.6、修饰符和转换器
        • 2.7、修饰符串联

一、defineProps() 和 defineEmits()

组件之间通讯,通过 props 和 emits 进行通讯,是单向数据流,
子组件不能改变父组件传递给它的 prop 属性,推荐的做法是它抛出事件,通知父组件自行改变绑定的值。

为了在声明 props 和 emits 选项时获得完整的类型推导支持,我们可以使用 defineProps 和 defineEmits API,它们将自动地在 <script setup> 中可用:

  • 父组件:
<template><div><ChildMy v-model:count="count" />{{ count }}</div>
</template><script setup>import ChildMy from './child.vue'import { ref } from 'vue' const count = ref(1)
</script>
  • 子组件:
<template><div>{{ props.count }}<button @click="updatedCount">child btn</button></div>
</template><script setup>
const props = defineProps(["count"]);
const emit = defineEmits(["update:count"]);const updatedCount = () => {emit('update:count', props.count + 1)
}
</script>
  • defineProps 和 defineEmits 都是只能在

二、defineModel() 的双向绑定

这个宏可以用来声明一个双向绑定 prop,通过父组件的 v-model 来使用。

在底层,这个宏声明了一个 model prop 和一个相应的值更新事件。如果第一个参数是一个字符串字面量,它将被用作 prop 名称;否则,prop 名称将默认为 “modelValue”。在这两种情况下,你都可以再传递一个额外的对象,它可以包含 prop 的选项和 model ref 的值转换选项。

defineModel() 的双向绑定是在编译之后,创建了一个model的ref变量以及一个modelValue的props,并且watch了props中的modelValue;当子组件中的modelValue更新时,会触发update:modelValue事件,当父组件接收到这个事件时候,同时更新父组件的变量。

2.1、基础示例
  • 父组件:
<template><div><ChildMy v-model="message"/>{{ message }}</div>
</template><script setup>import ChildMy from './child.vue'import { ref } from 'vue' const message = ref('hello')
</script>
  • 子组件:
<template><div>{{ message }}<button @click="updatedMsg">child btn</button></div>
</template><script setup>
const message = defineModel()const updatedMsg = () => {message.value = `world`
}
</script>
2.2、定义类型
  • 子组件:
<template><div>{{ message }}<button @click="updatedMsg">child btn</button></div>
</template><script setup>
const message = defineModel({ type: String })const updatedMsg = () => {message.value = `world`
}
</script>
2.3、声明prop名称
  • 父组件:
<template><div><ChildMy v-model:count="count"/>{{ count }}</div>
</template><script setup>import ChildMy from './child.vue'import { ref } from 'vue' const count = ref(1)
</script>
  • 子组件:
<template><div>{{ count }}<button @click="updatedCount">child btn</button></div>
</template><script setup>
const count = defineModel("count")
const updatedCount = () => {count.value ++
}
</script>
2.4、其他声明
  • 子组件:
<template><div>{{ count }}<button @click="updatedCount">child btn</button></div>
</template><script setup>
const count = defineModel("count", { type: Number, default: 0 , required: true})
const updatedCount = () => {count.value ++
}
</script>
2.5、绑定多个值
  • 父组件:
<template><div><ChildMy v-model:count="count" v-model:person="person" />{{ person }} - {{ count }}</div>
</template><script setup>
import ChildMy from './components/child.vue'
import { ref,reactive  } from 'vue'
const count = ref(1)
const person = reactive ({name: 'Lucy',age: 11})
</script>
  • 子组件:
<template><div>{{ person }} - {{ count }}<button @click="updatedData">child btn</button></div>
</template><script setup>
const person = defineModel("person")
const count = defineModel("count")const updatedData = () => {count.value ++person.value.age = 22person.value.name = "lilei"
}
</script>
2.6、修饰符和转换器

为了获取 v-model 指令使用的修饰符,我们可以像这样解构 defineModel() 的返回值:

const [modelValue, modelModifiers] = defineModel()

当存在修饰符时,我们可能需要在读取或将其同步回父组件时对其值进行转换。我们可以通过使用 get 和 set 转换器选项来实现这一点:

  • 父组件:
<template><div><ChildMy v-model.trim="message"/>{{ message }}</div>
</template><script setup>import ChildMy from './child.vue'import { ref } from 'vue' const message = ref(' hello ')
</script>
  • 子组件:
<template><div>{{ message }}<button @click="updatedMsg">child btn</button></div>
</template><script setup>
const [message, modelModifiers] = defineModel({set(value) {if (modelModifiers.trim) {value=value?.trim()}return value}
})const updatedMsg = () => {message.value += ` world`
}
</script>
2.7、修饰符串联
  • 父组件:
<template><div><ChildMy v-model.trim.lowercase="message"/>{{ message }}</div>
</template><script setup>import ChildMy from './child.vue'import { ref } from 'vue' const message = ref('Hello')
</script>
  • 子组件:
<template><div>{{ message }}<button @click="updatedMsg">child btn</button></div>
</template><script setup>
const [message, modelModifiers] = defineModel({get(value) {if (modelModifiers.trim) {value=value?.trim()}if (modelModifiers.lowercase) {value=value?.toLowerCase();}return value},set(value) {if (modelModifiers.trim) {value=value?.trim()}if (modelModifiers.lowercase) {value=value?.toLowerCase();}return value}
})const updatedMsg = () => {message.value += `World`
}
</script>

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Redis(三)
  • 27、美国国家冰雪中心(NSIDC)海冰密集度月数据下载与处理
  • MFC窗口大小最大化最小化随拖动调整大小
  • Golang | Leetcode Golang题解之第283题移动零
  • 【Go系列】Go的UI框架Fyne
  • SQL Server中非结构化数据的存储神器:文件表的魔力
  • 21 B端产品经理之技术常识(1)
  • Python | Leetcode Python题解之第284题窥视迭代器
  • Alternating Sum
  • web基础,http协议,apache概念及nginx
  • C#小结:string、double、TimeSpan等常见类型的小结和坑点
  • mysql的存储过程:
  • go操作aws s3
  • RemakePython
  • 24年第三届钉钉杯大学生大数据挑战赛
  • 【Leetcode】101. 对称二叉树
  • angular2 简述
  • CSS 三角实现
  • IDEA常用插件整理
  • js 实现textarea输入字数提示
  • js面向对象
  • Sass Day-01
  • Theano - 导数
  • vue-cli3搭建项目
  • vue-router的history模式发布配置
  • 阿里研究院入选中国企业智库系统影响力榜
  • 从PHP迁移至Golang - 基础篇
  • 关于 Cirru Editor 存储格式
  • ------- 计算机网络基础
  • 如何进阶一名有竞争力的程序员?
  • 我感觉这是史上最牛的防sql注入方法类
  • 用mpvue开发微信小程序
  • 栈实现走出迷宫(C++)
  • 自动记录MySQL慢查询快照脚本
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • ​草莓熊python turtle绘图代码(玫瑰花版)附源代码
  • # 利刃出鞘_Tomcat 核心原理解析(七)
  • ## 基础知识
  • #13 yum、编译安装与sed命令的使用
  • #java学习笔记(面向对象)----(未完结)
  • (3)医疗图像处理:MRI磁共振成像-快速采集--(杨正汉)
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (二)丶RabbitMQ的六大核心
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • (转)JVM内存分配 -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • (转载)跟我一起学习VIM - The Life Changing Editor
  • (轉貼) 2008 Altera 亞洲創新大賽 台灣學生成果傲視全球 [照片花絮] (SOC) (News)
  • ***原理与防范
  • .md即markdown文件的基本常用编写语法
  • .net core Swagger 过滤部分Api