背景:vue是单向数据流,子组件可以接收父组件的props,但是不能修改,否则会导致数据的应用流向变得难以理解。但是有时候我们希望子组件数据的修改,父组件的数据会随之变化。在vue2中提供了.sync修饰符,但是在vue3中不再支持.sync,取而代之的是v-model。
例子:封装一个MyDialog组件
父组件
<template>
<div class="home">
<el-button @click="dialogVisible = true">show</el-button>
<MyDialog v-model="dialogVisible"></MyDialog>
</div>
</template>
<script setup>
import MyDialog from '@/components/MyDialog.vue'
const dialogVisible = ref(false)
</script>
子组件
<template>
<el-dialog
v-model="modelValue"
title="Tips"
width="30%"
:before-close="handleClose"
>
<span>This is a message</span>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleClose">Cancel</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
const props = defineProps({
modelValue: {
type: Boolean,
default: false,
}
})
const emit = defineEmits(['update:modelValue'])
function handleClose() {
emit('update:modelValue', false)
}
</script>
解析
在自定义组件中的v-model,会展开成:modelValue
和@update:modelValue
的形式(modelValue
是默认的prop,可以自己重新定义)
如组件
<MyDialog v-model="dialogVisible"></MyDialog>
会展开成
<MyDialog :modelValue="dialogVisible" @update:modelValue="newValue => dialogVisible = newValue"></MyDialog>
我们在子组件中emit('update:modelValue', newValue)
,父组件绑定的值就会随之修改。
自定义prop名字
默认情况下,v-model 在组件上都是使用
modelValue
作为 prop,并以update:modelValue
作为对应的事件。我们可以通过给 v-model 指定一个参数来更改这些名字。
父组件
例如,我们将prop名字定义为show:
<template>
<div class="home">
<el-button @click="dialogVisible = true">show</el-button>
<MyDialog v-model:show="dialogVisible"></MyDialog>
</div>
</template>
<script setup>
import MyDialog from '@/components/MyDialog.vue'
const dialogVisible = ref(false)
</script>
子组件
子组件在defineProps中接收show
属性,同样的emit的时候也是emit('update:show', newValue)
。
<template>
<el-dialog
v-model="show"
title="Tips"
width="30%"
:before-close="handleClose"
>
<span>This is a message</span>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleClose">Cancel</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
const props = defineProps({
show: {
type: Boolean,
default: false,
}
})
const emit = defineEmits(['update:show'])
function handleClose() {
emit('update:show', false)
}
</script>
网友评论