Vue3自定义组件里数据双向绑定的实现

news/2024/11/30 4:16:19/

一、组合式API里的写法

1、defineModel

defineModel()返回的值是一个ref,它可以像其他ref一样被访问以及修改,不过它能起到在父组件和当前变量之间的双向绑定的作用。

  • 它的.value和父组件的v-model的值一起更新
  • 当它的子组件变更了,会触发父组件绑定的值一起更新

因为defineModel声明了一个prop,你可以通过给它传递选项,来声明底层prop的选项

javascript">const model = defineModel('modelValue', {
requiew: true, // 必填
default: 0, // 默认值
type: Number // 类型
})

注意:该写法需Vue3.2.0及以上版本才支持

 

1个数据的双向绑定

javascript">// 父组件<template><p>{{ data }}</p>
<button @click="data = 'xxx2'">修改子组件数据</button><Subcomponent v-model="data" /></template><script lang="ts" setup>import { ref } from 'vue'
import Subcomponent from './components/Subcomponent.vue'const data = ref('xxx1')</script>
javascript">// 子组件
<template><h1>{{ modelValue }}</h1>
<button @click="updateData('xxx2')">修改父组件的数据</button></template><script lang="ts" setup>import { defineModel } from 'vue'const modelValue = defineModel()const updateData = (e: string) => {modelValue.value = e
}</script>

 

多个数据的双向绑定

javascript">// 父组件<template><p>{{ data1 }}</p>
<p>{{ data2 }}</p>
<button @click="data1 = 'xxx2'">修改子组件的数据1</button>
<button @click="data2 = 'xxx2'">修改子组件的数据2</button><Subcomponent v-model:data1="data1" v-model:data2="data2" /></template><script lang="ts" setup>import { ref } from 'vue'
import Subcomponent from './components/Subcomponent.vue'const data1 = ref('data1')
const data2 = ref('data2')</script>
javascript">// 子组件
<template><h1>{{ data1 }}</h1>
<h1>{{ data2 }}</h1>
<button @click="updateData1('xxx1')">修改父组件的数据1</button>
<button @click="updateData2('xxx2')">修改父组件的数据2</button></template><script lang="ts" setup>import { defineModel } from 'vue'const data1 = defineModel('data1')
const data2 = defineModel('data2')const updateData1 = (e: string) => {data1.value = e
}const updateData2 = (e: string) => {data2.value = e
}</script>

2、v-model

1个数据的双向绑定

javascript">// 父组件<template><p>{{ data }}</p>
<button @click="data = 'xxx2'">修改子组件数据</button><Subcomponent v-model="data" /></template><script lang="ts" setup>import { ref } from 'vue'
import Subcomponent from './components/Subcomponent.vue'const data = ref('xxx1')</script>
javascript">// 子组件
<template><h1>{{ modelValue }}</h1>
<button @click="updateData('xxx2')">修改父组件的数据</button></template><script lang="ts" setup>const props = defineProps<{ modelValue: string }>()
const emit = defineEmits<(e: "update:modelValue", value: string) => void>()const updateData = (e: string) => {emit('update:modelValue', e)
}</script>

多个数据的双向绑定

javascript">// 父组件<template><p>{{ data1 }}</p>
<p>{{ data2 }}</p>
<button @click="data1 = 'xxx2'">修改子组件的数据1</button>
<button @click="data2 = 'xxx2'">修改子组件的数据2</button><Subcomponent v-model:data1="data1" v-model:data2="data2" /></template><script lang="ts" setup>import { ref } from 'vue'
import Subcomponent from './components/Subcomponent.vue'const data1 = ref('data1')
const data2 = ref('data2')</script>
javascript">// 子组件
<template><h1>{{ modelValue }}</h1>
<button @click="updateData1('xxx2')">修改父组件的数据1</button>
<button @click="updateData2('xxx2')">修改父组件的数据2</button></template><script lang="ts" setup>const props = defineProps<{ 
data1: string, 
data2: string 
}>()const emit = defineEmits<{
(e: "update:data1", value: string): void,
(e: "update:data2", value: string): void,
}>()const updateData1 = (e: string) => {emit('update:data1', e)
}const updateData2 = (e: string) => {emit('update:data2', e)
}
</script>

3、常规写法

javascript">// 子组件<template><p>{{ p_data }}</p><button @click="updateData('xxx')">子组件按钮</button>
</template><script lang="ts" setup>const props = defineProps<{ p_data: string }>()const emit = defineEmits<(e: "update", value: string) => void> ()function updateData(e: string) {emit('update', '修改父组件data')
}</script>
javascript">// 父组件<template><p>{{ data }}</p>
<button @click="data = 'xxx2'">修改子组件数据</button><Subcomponent :p_data="data" @update="updateData"/></template><script lang="ts" setup>import { ref } from 'vue'
import Subcomponent from './components/Subcomponent.vue'const data = ref('xxx1')function updateData(e: string) {data.value = e
}</script>

二、选项式API里的写法

javascript">// 子组件
<template>
<input :value="modelValue" @input="handleInput" />
</template><script>export default {props: {modelValue: String // 定义v-model绑定的属性名},emits: ['update:modelValue'] // 声明可以发出的自定义事件
}</script>
javascript">// 父组件
<template>
<CustomInpput v-model="inputValue" />
</template><script>
import CustomInput from './CustomInput.vue'export default {components: {CustomInput},data() {return {inputValue: ''}}
}
</script>

三、案例 —— 自定义勾选按钮

javascript"><template><div class="component-container"><i class="check-btn" v-if="!isChecked" @click="handleCheck(true)"></i><i class="check-btn active" v-if="isChecked" @click="handleCheck(false)"></i></div>
</template><script lang="ts" setup>import { ref, defineModel } from 'vue'const emits = defineEmits(['change'])const isChecked = defineModel('isChecked', { default: false })function handleCheck(e: boolean) {isChecked.value = eemits('change',  isChecked.value)
}</script><style lang="scss" scope>
.component-container {.check-btn {display: block;border: 1px solid #d4d4d9;width: 15px;height: 15px;cursor: pointer;&.active {background: #0055FF;}}
}
</style>
<CheckBtn @change="(...args) => managementFieldCheckAll(...args, it.value)"/>


http://www.ppmy.cn/news/1551093.html

相关文章

人力资源项目学习

特点 特点1&#xff1a;对象转化为树形结构 好处 将对象转化为树形结构&#xff08;例如&#xff1a;菜单、权限等&#xff09;有许多实际的好处&#xff0c;特别是在处理具有层级关系的数据时。通过您的代码实现的树形结构转换&#xff0c;可以带来以下几个显著优势&#x…

如何利用ArcGIS探究环境和生态因子对水体、土壤和大气污染物的影响?

原文&#xff1a;如何利用ArcGIS探究环境和生态因子对水体、土壤和大气污染物的影响&#xff1f;https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247630247&idx8&sn2debedc63a42cfd24ed4c8afbb8c575d&chksmfa8dbc40cdfa3556dc0ec660d00fcd7e8c9a9ca75a8…

Web登录页面设计

记录第一个前端界面&#xff0c;暑假期间写的&#xff0c;用了Lottie动画和canvas标签做动画&#xff0c;登录和注册也连接了数据库。 图片是从网上找的&#xff0c;如有侵权私信我删除&#xff0c;谢谢啦~

网络安全内容整理一

前言 整理博客&#xff0c;统一到常用的站点。 基础知识 网络安全的三个基本属性&#xff1a;CIA三元组 机密性 Confidentiality完整性 Integrity可用性 Availability 网络安全的基本需求 可靠性、可用性、机密性、完整性、不可抵赖性、可控性、可审查性、真实性 网络安…

小游戏聚合SDK的工具类封装

文章目录 前言工具类单例日志打印输入框的封装前言 之前的文章写了如何开发小游戏聚合SDK,既然是聚合SDK,工具类的封装也比较重要,做好基础搭建后续在接入其他渠道的时候能大大减少工作量。 工具类 单例 初始化的配置信息,比如应用ID 、渠道ID等需要全局使用,而且初始…

2024下半年——【寒假】自学黑客计划(网络安全)

CSDN大礼包&#xff1a;&#x1f449;基于入门网络安全/黑客打造的&#xff1a;&#x1f449;黑客&网络安全入门&进阶学习资源包 前言 什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&a…

金铲铲S13双城之战自动拿牌助手

金铲铲S13双城之战自动拿牌助手 基于python&#xff0c;pyautogui和金铲铲自带备战助手实现 B站视频演示效果 shuangcheng.py import timeimport pyautogui import datetimeprint(请关注您的分辨率&#xff0c;此程序需要配合thumbs_x_y.txt文件同时使用) print(简介&#x…

【C++】数据类型(上)

C规定在创建一个变量或一个常量时&#xff0c;必须要指定出相应的数据类型&#xff0c;否则无法给变量分配内存 数据类型存在意义&#xff1a;给变量分配合适的内存空间。 1.1 整型 整型作用&#xff1a;整型变量表示的整数类型的数据。 C中能够表示整型类型的有以下几种…