v-model 基本用法
prop: modelValue
事件:update:modelValue
<!-- App.vue --><template><div><h1>我是父组件</h1><div>isShow: {{ isShow }}</div><div><button @click="isShow = !isShow">开关</button></div><br><BVue v-model="isShow"></BVue></div>
</template><script setup lang="ts">
import { ref,reactive, isShallow } from "vue";
import BVue from "./components/B.vue";
const isShow = ref<boolean>(true);
</script><style scoped></style>
<!-- B.vue --><template><div v-if="modelValue" class="wrap"><div>modelValue:{{ modelValue }}</div><h1>我是B子组件</h1><button @click="close">关闭</button><br>内容:<input type="text"></div>
</template><script setup lang="ts">defineProps<{modelValue: boolean
}>()
const emit = defineEmits(['update:modelValue'])
const close = ()=> {emit('update:modelValue', false)
}
</script><style scoped>
.wrap {width: 300px;height: 200px;border: 10px solid #ccc;
}
</style>
多个 v-model
<!-- App.vue -->
<template><div><h1>我是父组件</h1><div>isShow: {{ isShow }}</div><div>text: {{ text }}</div><div><button @click="isShow = !isShow">开关</button></div><br><BVue v-model:textVal="text" v-model="isShow"></BVue></div>
</template><script setup lang="ts">
import { ref,reactive, isShallow } from "vue";
import BVue from "./components/B.vue";
const isShow = ref<boolean>(true);
const text = ref<string>("hello");
</script><style scoped></style>
<!-- B.vue -->
<template><div v-if="modelValue" class="wrap"><div>modelValue:{{ modelValue }}</div><h1>我是B子组件</h1><button @click="close">关闭</button><br>text内容:<input @input="change" :value="textVal" type="text"></div>
</template><script setup lang="ts">defineProps<{modelValue: boolean,textVal: string
}>()
const emit = defineEmits(['update:modelValue','update:textVal'])
const close = ()=> {emit('update:modelValue', false)
}
const change = (e:Event)=> {// target 自行推断出为 EventTarget 类型,但此类型不能读取 value 属性,因此需要断言为 HTMLInputElement// 比如 element-plus 也是这么封装的const target = e.target as HTMLInputElementemit('update:textVal', target.value)
}
</script><style scoped>
.wrap {width: 300px;height: 200px;border: 10px solid #ccc;
}
</style>
自定义修饰符 Modifiers
<!-- App.vue -->
<template><div><h1>我是父组件</h1><div>isShow: {{ isShow }}</div><div>text: {{ text }}</div><div><button @click="isShow = !isShow">开关</button></div><br><BVue v-model:textVal.isBT="text" v-model="isShow"></BVue></div>
</template><script setup lang="ts">
import { ref,reactive, isShallow } from "vue";
import BVue from "./components/B.vue";
const isShow = ref<boolean>(true);
const text = ref<string>("hello");
</script><style scoped></style>
<!-- B.vue -->
<template><div v-if="modelValue" class="wrap"><div>modelValue:{{ modelValue }}</div><h1>我是B子组件</h1><button @click="close">关闭</button><br>text内容:<input @input="change" :value="textVal" type="text"></div>
</template><script setup lang="ts">const props = defineProps<{modelValue: boolean,textVal: string,textValModifiers?: {isBT: boolean}
}>()
const emit = defineEmits(['update:modelValue','update:textVal'])
const close = ()=> {emit('update:modelValue', false)
}
const change = (e:Event)=> {// target 自行推断出为 EventTarget 类型,但此类型不能读取 value 属性,因此需要断言为 HTMLInputElement// 比如 element-plus 也是这么封装的const target = e.target as HTMLInputElementemit('update:textVal', props?.textValModifiers?.isBT ? target.value + '备胎' : target.value)
}
</script><style scoped>
.wrap {width: 300px;height: 200px;border: 10px solid #ccc;
}
</style>