一般来说弹窗组件是单独抽离成组件放在components中方便代码阅读
一. 通过绑定子组件ref来操作弹窗的布尔值
父组件
<modelDialog ref="modelDialogs" />
<el-button type="primary" class="btn" @click="addModel">
ref点击弹出 </el-button>
const modelDialogs = ref(null)
const addModel = () => {
modelDialogs.value.centerDialogVisible = true
modelDialogs.value.addRef('ref点击弹出')
}
子组件
<template>
<div>
<el-dialog
v-model="centerDialogVisible"
title="新增"
width="50%"
align-center
>
<div>
ref弹出
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="centerDialogVisible = false"
>取消</el-button
>
<el-button
type="primary"
@click="centerDialogVisible = false"
>
确定
</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref } from 'vue';
const centerDialogVisible = ref(false)
const addRef = (value) => {
console.log(value, '我是父组件传值过来的')
}
defineExpose({
centerDialogVisible,
addRef
})
</script>
二. 通过v-model方式
通过v-model:XXX修饰绑定(默认绑定的modelValue)
父组件
<vmodelDialog
v-model:modelValue="flag"
v-model:str="vmodelDialogs.str"
/>
子组件处理props
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
str: {
type: String,
default: ''
}
})
// 添加emit事件
const emit = defineEmits(['update:modelValue', 'update:str'])
// 确定
const addConfirm = () => {
emit('update:modelValue', false)
}
// 取消
const addCancel = () => {
emit('update:modelValue', false)
}
在父组件中绑定一个 v-model:str=“vmodelDialogs.str”
在子组件中通过computed方式处理子组件的输入
const int = computed({
get () {
return props.str
},
set (value) {
console.log(value, '>><<')
emit('update:str', value)
}
})
Vue3 v-model文档地址
最后放上全代码
父组件
<template>
<div>
<modelDialog ref="modelDialogs" />
<el-button type="primary" class="btn" @click="addModel"
>ref点击弹出</el-button
>
<p>子组件</p>
<vmodelDialog
v-model:modelValue="flag"
v-model:str="vmodelDialogs.str"
/>
<!-- @update:modelValue="(newValue) => (flag = newValue)" -->
<el-button type="primary" class="btn" @click="addVmodel"
>点击v-model弹出</el-button
>
<p>父组件输入</p>
<el-input
v-model="vmodelDialogs.str"
placeholder="父组件输入"
></el-input>
</div>
</template>
<script setup>
import { reactive } from 'vue';
import modelDialog from './components/modelDialog.vue';
import vmodelDialog from './components/vmodelDialog.vue';
const modelDialogs = ref(null)
const flag = ref(false)
const vmodelDialogs = reactive({
flag: false,
str: '修改'
})
const addModel = () => {
modelDialogs.value.centerDialogVisible = true
modelDialogs.value.addRef('ref点击弹出')
}
const addVmodel = () => {
flag.value = !flag.value
console.log(vmodelDialogs)
}
</script>
<style lang="scss" scoped>
.btn {
margin: 10px 0;
}
</style>
ref弹窗组件
<template>
<div>
<el-dialog
v-model="centerDialogVisible"
title="新增"
width="50%"
align-center
>
<div>
<el-form>
<el-row :gutter="24">
<el-col :span="12">
<el-form-item label="名称">
<el-input></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="名称">
<el-input></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="名称">
<el-input></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="名称">
<el-input></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="centerDialogVisible = false"
>取消</el-button
>
<el-button
type="primary"
@click="centerDialogVisible = false"
>
确定
</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref } from 'vue';
const centerDialogVisible = ref(false)
const addRef = (value) => {
console.log(value, '我是父组件传值过来的')
}
defineExpose({
centerDialogVisible,
addRef
})
</script>
v-model弹窗组件
<template>
<div>
<el-input v-model="int" placeholder="子组件请输入内容"></el-input>
<el-dialog v-model="val" title="新增" width="50%" align-center>
<div>
<el-form>
<el-row :gutter="24">
<el-col :span="12">
<el-form-item label="名称">
<el-input></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="名称">
<el-input></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="名称">
<el-input></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="名称">
<el-input></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="addCancel">取消</el-button>
<el-button type="primary" @click="addConfirm">
确定
</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { computed, onMounted, ref } from 'vue';
// defineProps(['vmodelDialogs'])
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
str: {
type: String,
default: ''
}
})
const init = ref(false)
const emit = defineEmits(['update:modelValue', 'update:str'])
watch(() => props.modelValue, (newValue, oldValue) => {
console.log(newValue, '新的值')
})
const int = computed({
get () {
return props.str
},
set (value) {
console.log(value, '>><<')
emit('update:str', value)
}
})
const val = computed(() => {
return props.modelValue
})
// 确定
const addConfirm = () => {
emit('update:modelValue', false)
}
// 取消
const addCancel = () => {
emit('update:modelValue', false)
}
onMounted(() => {
console.log(props.flag, 'vm')
})
</script>