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} />
},
})