使用 Vue3
script setup
语法
<template>
<input type="text" v-model="val" @input="handleInput">
</template>
<script setup>
import {ref, defineProps, defineEmits, watch} from 'vue'
const props = defineProps({
modelValue: {
type: String,
default: ''
},
})
const emit = defineEmits(['update:modelValue'])
const val = ref('')
watch(() => props.modelValue, nVal => val.value = nVal, {
immediate: true
})
const handleInput = () => emit('update:modelValue', val.value)
</script>
您不能指望
v-model
为您隐式更新底层元素。换句话说,您仍然需要在组件本身内处理该问题,并公开 modelValue
作为其真正起作用的道具。类似这样的东西:
<template>
<input
type="text"
@input="onChanged"
:value="modelValue"
:class="'input-text ' + additionalClass"
:placeholder="placeholder" />
</template>
<script>
// InputText.vue
import { defineComponent } from "vue"
export default defineComponent({
name: 'InputText',
emits: ['update:modelValue'],
props: {
modelValue: String,
placeholder: {
type: String,
default: ''
},
additionalClass: {
type: String,
default: ''
}
},
setup(props, { emit }) {
function onChanged(e) {
emit('update:modelValue', e.currentTarget.value);
}
return {
onChanged
}
}
})
</script>
VueUse 助手
useVModel
可以简化子组件中的 v-model
处理,请参阅 https://vueuse.org/core/usevmodel/#usage
<script lang="ts" setup>
import { useVModel } from '@vueuse/core'
const props = defineProps<{
modelValue: string
}>()
const emit = defineEmits(['update:modelValue'])
const model = useVModel(props, 'modelValue', emit)
</script>
<template>
<input type="text" v-model="model" />
</template>
使用
OPTIONS API
语法
<template>
<input type="text" v-model="val" @input="updateText" :value="modelValue">
</template>
<script scoped>
export default {
props: {
modelValue: String,
},
methods: {
updateText(event){
this.$emit('update:modelValue', event.currentTarget.value)
}
}
}
</script>
从 vue 3.4 开始推荐的方法是使用
defineModel()
宏。
https://vuejs.org/guide/components/v-model
根据您的回答,代码将如下所示(使用 TypeScript 类型):
<script setup lang="ts">
const model = defineModel();
const { placeholder, additionalClass } = defineProps<{
placeholder: string
additionalClass: string
}>();
</script>
<template>
<input
type="text"
v-model="model"
:class="'input-text ' + additionalClass"
:placeholder="placeholder"
/>
</template>
在你的父组件中
<script setup lang="ts">
const textInput = ref('');
</script>
<template>
<SomeInput
v-model="textInput"
placeholder="placeholder"
additionalClass="some-class"
/>
</template>
在vue2中,这个东西起作用了:
您的InputText组件
<template>
<input :value="value"
@input="({target}) => $emit('input', target.value)"/>
</template>
<script>
export default {
props: {
value: {}
}
}
您的父组件
<template>
<inputText v-model="inputValue"/>
</template>
<script>
export default {
components: {inputText},
data: () => ({
inputValue: null
})
}
</script>