封装子组件的v-model双向绑定
单个v-model
父组件
html
<template>
<!-- 就像用普通 input -->
<MyInput v-model="text" />
<p>父组件:{{ text }}</p>
</template>
<script setup>
import { ref } from 'vue'
const text = ref('hello')
</script>子组件
js
<template>
<input
:value="modelValue"
@input="onInput"
/>
</template>
<script setup>
// 1. 声明接收
const props = defineProps({
modelValue: String
})
// 2. 声明事件
const emit = defineEmits(['update:modelValue'])
function onInput(e) {
// 3. 抛新值
emit('update:modelValue', e.target.value)
}
</script>多个v-model
父组件
js
<template>
<UserCard
v-model:name="name"
v-model:age="age"
/>
<p>name:{{ name }} age:{{ age }}</p>
</template>
<script setup>
import { ref } from 'vue'
const name = ref('Tom')
const age = ref(18)
</script>子组件
js
<template>
<input :value="name" @input="e=>$emit('update:name',e.target.value)" />
<input :value="age" @input="e=>$emit('update:age', e.target.value)" />
</template>
<script setup>
defineProps({
name: String,
age: [String, Number]
})
</script>带.lazy/.number等修饰符的的v-model
父组件
js
<template>
<MyInput v-model.number="num" placeholder="输入自动变 number" />
<p>num 值:{{ num }}(类型:{{ typeof num }})</p>
</template>
<script setup>
import { ref } from 'vue'
const text = ref('abc')
const num = ref(0)
</script>子组件
js
<script setup>
const props = defineProps({
modelValue: [String, Number],
modelModifiers: { default: () => ({}) } // 接收修饰符
})
const emit = defineEmits(['update:modelValue'])
function onInput(e) {
let val = e.target.value
if (props.modelModifiers.number) {
val = Number(val) // .number 自动转数值
}
emit('update:modelValue', val)
}
</script>