Vue3 中 v-model 的背后逻辑
在 vue3 中 v-model 会被编译成什么呢?是否可以不使用 v-model 呢?
我最近在写一些 TSX 组件的时候遇到了这个问题,看了一下 naive-ui 的代码,发现他们都是用 tsx 编写 vue3 组件的,详情看 这里

在 208 行的时候,有 2 个 call 的方法,分别考虑了
使用
v-model:height="ref"和使用:height="ref"&:on-update-height="e => ref = e"的情况对应到
TSX里就是v-model={ref.value}以及height={ref.value}&on-update-height={e => ref.value = e}
列子
vue
<script setup>
import { ref } from 'vue'
import Comp from './Input.tsx'
const value1 = ref('')
const value2 = ref('')
</script>
<template>
<h3>使用 v-model:value: {{ value2 }}</h3>
<Comp v-model:value="value2" />
<br />
<h3>不使用: {{ value1 }}</h3>
<Comp :value="value1" :on-update-value="(e) => (value1 = e)" />
</template>tsx
import { defineComponent, type PropType } from 'vue'
type Props = {
value?: string
onUpdateValue?: (e: string) => void
['onUpdate:value']?: (e: string) => void
}
const props = {
value: {
type: String as PropType<Props['value']>,
default: '',
},
onUpdateValue: {
type: Function as PropType<Props['onUpdateValue']>,
default: () => () => {},
},
['onUpdate:value']: {
type: Function as PropType<Props['onUpdate:value']>,
default: () => () => {},
},
}
export default defineComponent<Props>({
name: 'Input',
props,
setup: (props) => {
const handleInput: HTMLInputElement['oninput'] = (e) => {
const { onUpdateValue, 'onUpdate:value': _onUpdateValue } = props
if (e.target instanceof HTMLInputElement) {
onUpdateValue && onUpdateValue(e.target.value)
_onUpdateValue && _onUpdateValue(e.target.value)
}
}
return () => <input value={props.value} onInput={handleInput} />
},
})