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>

浙公网安备 33010602011771号