vue3.0 goes deep into v-model and uses multiple v-models
v-model principle
Principle: In fact, it is a syntactic sugar composed of props and emit
Changes to default values
prop:value -> modelValue;
事件:input -> update:modelValue;
Note: The .sync modifier of v-bind and the model option of the component have been removed (because in order to implement update:modelValue value update, the previous .sync writing is temporarily used)
Note 2: Added support for multiple v-models
Note 3: Added support for custom modifiers
V-mode implements communication between parent and child components
Parent component Main.vue
< template>
< div>
< div> Main - flag - {
{
flag } } < / div>
< button @click= "flag = !flag" > 修改 flag< / button>
< Dialog v- model= "flag" / >
< / div>
< / template>
< script setup lang= "ts" >
import {
ref } from 'vue'
let flag = ref< Boolean> ( true )
import Dialog from './childCom/Dialog.vue'
< / script>
< script lang= "ts" >
export default {
name: 'Main' ,
}
< / script>
Child component Dialog.vue
< template>
< div v- if = "modelValue" class = "dialog" >
< div class = "dialog-header" >
< span> 标题< / span>
< button @click= "close" > 关闭< / button>
< / div>
< div class = "dialog-main" >
{
{
modelValue } }
< / div>
< / div>
< / template>
< script setup lang= "ts" >
type Props = {
modelValue: Boolean
}
defineProps< Props> ( )
const emit = defineEmits ( [ 'update:modelValue' ] )
const close = ( ) => {
emit ( 'update:modelValue' , false )
}
< / script>
< script lang= "ts" >
export default {
name: 'Dialog' ,
}
< / script>
< style lang= "scss" scoped>
. dialog {
width: 400 px;
height: 250 px;
border: 1 px solid #ccc;
& - header {
height: 40 px;
border: 1 px solid #ccc;
}
& - body {
height: 210 px;
}
}
< / style>
Effect
In the parent component, when you click to modify the flag, you can control the display and hiding of the dialog component
When you click close in the subcomponent dialog, you can modify the value of the flag of the parent component
v-model uses multiple
main.view
< template>
< div>
< div> Main - 标志 - {
{
flag } } 标题 - {
{
title } } < / div>
< button @click= "flag = !flag" > 修改 flag< / button>
< Dialog v- model= "flag" v- model: title= "title" / >
< / div>
< / template>
< script setup lang= "ts" >
import {
ref } from 'vue'
let flag = ref< Boolean> ( true )
import Dialog from './childCom/Dialog.vue'
let title = ref< String> ( '我是小渣亮' )
< / script>
< script lang= "ts" >
export default {
name: 'Main' ,
}
< / script>
< style lang= "scss" scoped> < / style>
dialog.view
< template>
< div v- if = "modelValue" class = "dialog" >
< div class = "dialog-header" >
< span> 标题 - {
{
title } } < / span>
< button @click= "close" > 关闭< / button>
< / div>
< div class = "dialog-main" >
< button @click= "changTitle" > 修改 标题< / button>
{
{
modelValue } }
< / div>
< / div>
< / template>
< script setup lang= "ts" >
type Props = {
modelValue: Boolean
title: String
}
defineProps< Props> ( )
const emit = defineEmits ( [ 'update:modelValue' , 'update:title' ] )
const close = ( ) => {
emit ( 'update:modelValue' , false )
}
const changTitle = ( ) => {
emit ( 'update:title' , '我就是狗啊' )
}
< / script>
< script lang= "ts" >
export default {
name: 'Dialog' ,
}
< / script>
< style lang= "scss" scoped>
. dialog {
width: 400 px;
height: 250 px;
border: 1 px solid #ccc;
& - header {
height: 40 px;
border: 1 px solid #ccc;
}
& - body {
height: 210 px;
}
}
< / style>
Effect
v-model custom modifier
Custom modifiers for v-model
You can also add custom modifiers to another v-model:title
Custom modifiers for v-model
main.view
< template>
< div>
< div> Main - 标志 - {
{
flag } } 标题 - {
{
title } } < / div>
< button @click= "flag = !flag" > 修改 flag< / button>
< ! -- 添加xzl -- >
< ! -- < Dialog v- model. xzl= "flag" v- model: title= "title" / > 修饰符 -- >
< ! -- 没有添加 xzl修饰符 -- >
< Dialog v- model= "flag" v- model: title= "title" / >
< B / >
< C / >
< / div>
< / template>
< script setup lang= "ts" >
import {
ref } from 'vue'
let flag = ref< Boolean> ( true )
import Dialog from './childCom/Dialog.vue'
import B from './childCom/B.vue'
import C from './childCom/C.vue'
let title = ref< String> ( '我是小渣亮' )
< / script>
< script lang= "ts" >
export default {
name: 'Main' ,
}
< / script>
< style lang= "scss" scoped> < / style>
dialog.view
< template>
< div v- if = "modelValue" class = "dialog" >
< div class = "dialog-header" >
< span> 标题 - {
{
title } } < / span>
< button @click= "close" > 关闭< / button>
< / div>
< div class = "dialog-main" >
< button @click= "changTitle" > 修改 标题< / button>
{
{
modelValue } }
< / div>
< / div>
< / template>
< script setup lang= "ts" >
type Props = {
modelValue: Boolean
title: String
modelModifiers? : {
xzl: Boolean
}
}
const propsData = defineProps< Props> ( )
const emit = defineEmits ( [ 'update:modelValue' , 'update:title' ] )
const close = ( ) => {
emit ( 'update:modelValue' , false )
}
const changTitle = ( ) => {
if ( propsData. modelModifiers? . xzl) {
emit ( 'update:title' , '我就是狗之zxl' )
} else {
emit ( 'update:title' , '我就是狗之非xzl' )
}
}
< / script>
< script lang= "ts" >
export default {
name: 'Dialog' ,
}
< / script>
< style lang= "scss" scoped>
. dialog {
width: 400 px;
height: 250 px;
border: 1 px solid #ccc;
& - header {
height: 40 px;
border: 1 px solid #ccc;
}
& - body {
height: 210 px;
}
}
< / style>
Effect