v-model:组件数据双向绑定 与及修饰符的实现
组件的v-model实现
注意: v-model 只能绑定ref数据。不能绑定reactive响应数据。因为reactive绑定时,无法同步。
方法一:默认绑定
组件test.vue
<template> <view><input type="text" :value="modelValue" @input="instance.emit('update:modelValue', $event.detail.value)"/></view> </template> <script setup> import { getCurrentInstance } from 'vue' defineEmits(['update:modelValue']) const props = defineProps({ modelValue: String // modelValue 是默认的 }) var instance = getCurrentInstance() </script>
父组件代码:
<template> <test v-model="title"></test> <input type="text" v-model="title"/> </template> <script setup> import { ref } from 'vue' const title = ref('请输入') </script>
方法二:绑定多个v-model
组件test.vue
<template> <view><input type="text" :value="firstName" @input="instance.emit('update:firstName', $event.detail.value)"/></view> <view><input type="text" :value="lastName" @input="instance.emit('update:lastName', $event.detail.value)"/></view> </template> <script setup> import { getCurrentInstance } from 'vue' defineEmits(['update:firstName', 'update:lastName']) const props = defineProps({ firstName: String, lastName: String }) var instance = getCurrentInstance() </script>
父组件代码:
<template> <test v-model:firstName="firstName" v-model:lastName="lastName"></test> <input type="text" v-model="firstName"/> <input type="text" v-model="lastName"/> </template> <script setup> import { ref } from 'vue' const firstName = ref('姓氏') const lastName = ref('名') </script>
方法三:定义计算属性,实现v-model
<!-- CustomInput.vue --> <script setup> import { computed } from 'vue' const props = defineProps(['modelValue']) const emit = defineEmits(['update:modelValue'])
// const value = computed({ get() { return props.modelValue }, set(value) { emit('update:modelValue', value) } }) </script> <template> <input v-model="value" /> </template>
扩展知识: 给v-model增加自定义修饰符:
v-model支持常用修饰符,比如 trim等。我们也可以自定义不同的修饰符来实现相应的功能。比如我要定义 toLowerCase 修饰符用于同步时将值转换成小写字母。
组件text.vue
<template> <view><input type="text" :value="modelValue" @input="changeValue($event)"/></view> </template> <script setup> import { getCurrentInstance } from 'vue' defineEmits(['update:modelValue']) const props = defineProps({ modelValue: String, // 这是v-model内置 modelModifiers: { // 这是v-model系统内置的修饰符props函数 default: () => ({}) } }) var instance = getCurrentInstance() var changeValue = function($event){ var value = $event.detail.value // 此时表示调用了修饰符 toLowerCase,在这里实现修饰符逻辑 if(props.modelModifiers.toLowerCase) value = value.toLowerCase() instance.emit('update:modelValue', value ) } </script>
父组件代码:
<template> <test v-model.toLowerCase="title"></test> <input type="text" v-model="title"/> </template> <script setup> import { ref } from 'vue' const title = ref('请输入') </script>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具