导航

v-model 其实是一个语法糖 通过 props 和 emit 组合而成的
value -> modelValue;input -> update:modelValue;v-bind 的 .sync 修饰符和组件的 model 选项已移除v-modelModifiers子组件
<template>
<div v-if='propData.modelValue' class="dialog">
<div class="dialog-header">
<div>标题</div><div @click="close">x</div>
</div>
<div class="dialog-content">
内容
</div>
</div>
</template>
<script setup lang='ts'>
type Props = {
modelValue: boolean
}
const propData = defineProps<Props>()
const emit = defineEmits(['update:modelValue'])
const close = () => {
emit('update:modelValue', false)
}
</script>
<style lang='less'>
.dialog{
width: 300px;
height: 300px;
border: 1px solid #ccc;
position: fixed;
left:50%;
top:50%;
transform: translate(-50%,-50%);
&-header{
border-bottom: 1px solid #ccc;
display: flex;
justify-content: space-between;
padding: 10px;
}
&-content{
padding: 10px;
}
}
</style>
父组件
<template>
<button @click="show = !show">开关{{show}}</button>
<Dialog v-model="show"></Dialog>
</template>
<script setup lang='ts'>
import Dialog from "./components/Dialog/index.vue";
import {ref} from 'vue'
const show = ref(false)
</script>
<style>
</style>
子组件
<template>
<div v-if='modelValue' class="dialog">
<div class="dialog-header">
<div>标题---{{title}}</div><div @click="close">x</div>
</div>
<div class="dialog-content">
内容
</div>
</div>
</template>
<script setup lang='ts'>
type Props = {
modelValue: boolean,
title: string
}
const propData = defineProps<Props>()
const emit = defineEmits(['update:modelValue','update:title'])
const close = () => {
emit('update:modelValue',false)
emit('update:title','我要改变')
}
</script>
<style lang='less'>
.dialog{
width: 300px;
height: 300px;
border: 1px solid #ccc;
position: fixed;
left:50%;
top:50%;
transform: translate(-50%,-50%);
&-header{
border-bottom: 1px solid #ccc;
display: flex;
justify-content: space-between;
padding: 10px;
}
&-content{
padding: 10px;
}
}
</style>
父组件
<template>
<button @click="show = !show">开关{{show}} ----- {{title}}</button>
<Dialog v-model:title='title' v-model="show"></Dialog>
</template>
<script setup lang='ts'>
import Dialog from "./components/Dialog/index.vue";
import {ref} from 'vue'
const show = ref(false)
const title = ref('我是标题')
</script>
<style>
</style>
添加到组件 v-model 的修饰符将通过 modelModifiers prop 提供给组件。
父组件
<VModelVue v-model:textVal.isBt="text" v-model="isShow"></VModelVue>
子组件
<script setup lang="ts">
type Props = {
modelValue: boolean,
textVal: string,
textValModifiers?: {
isBt: boolean
}
}
const propsData = defineProps<Props>();
const emit = defineEmits(['update:modelValue', 'update:textVal']);
const change = (e: Event) => {
const target = e.target as HTMLInputElement;
emit('update:textVal', propsData?.textValModifiers?.isBt ? target.value + 'BT' : target.value);
}
</script>
子组件 - 默认值
<script setup lang='ts'>
const propData = defineProps<{
modelValue: boolean,
title?: string,
modelModifiers?: {
default: () => {}
}
titleModifiers?: {
default: () => {}
}
}>()
const emit = defineEmits(['update:modelValue', 'update:title'])
const close = () => {
console.log(propData.modelModifiers);
emit('update:modelValue', false)
emit('update:title', '我要改变')
}
</script>