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 HTMLInputElement
emit('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 HTMLInputElement
emit('update:textVal', props?.textValModifiers?.isBT ? target.value + '备胎' : target.value)
}
</script>
<style scoped>
.wrap {
width: 300px;
height: 200px;
border: 10px solid #ccc;
}
</style>