前几天被人问到过,当时挺懵的,回来看了看,发现原来是这样做的
效果图如下,只实现了一个最基本的,可以传入属性,也可以使用方法,后续需要什么,再往里面加
主要是通过v-model控制对话框的显示和隐藏,实现父子组件的双向数据绑定
- v-model用在组件上,默认绑定的值为modelValue,相当于v-model:modelValue。当然也可以自定义值
- 父组件中子组件标签里的内容,子组件用插槽进行接收
父组件
<template>
<div class="dialog">
<button @click.stop="showModel">显示对话框 -- {
{ show }}</button>
<Diglog
v-model="show"
:title="title"
@open="handleOpen"
@close="handleClose"
>
<p>插槽内容</p>
<template #footer>
<span>
<button @click="show = false">确定</button>
<button @click="show = false">取消</button>
</span>
</template>
</Diglog>
</div>
</template>
<script setup>
import { ref } from 'vue'
import Diglog from './components/Diglog.vue'
// 控制对话框显示/隐藏
let show = ref(false)
// 窗口标题
let title = ref('标题呀')
const showModel = () => {
show.value = true
}
const handleOpen = (a) => {
console.log('打开了' + '默认参数为' + a)
}
const handleClose = (a) => {
console.log('关闭了' + '默认参数为' + a)
}
</script>
子组件
<template>
<div class="box" ref="box" v-show="props.modelValue">
<i class="close" @click="closeModel">X</i>
<h3 class="title">{
{ props.title }}</h3>
<slot>插槽备用内容1</slot>
<footer class="footer">
<slot name="footer">插槽备用内容2</slot>
</footer>
</div>
</template>
<script setup>
import { defineProps, defineEmits, ref, watch } from 'vue'
const props = defineProps({
modelValue: {
type: Boolean,
default: false,
},
title: {
type: String,
default: '',
},
})
let box = ref(null)
const emits = defineEmits(['update:modelValue', 'open', 'close'])
document.addEventListener('click', function (e) {
if (!box.value.contains(e.target)) {
emits('update:modelValue', false)
}
})
const closeModel = () => {
emits('update:modelValue', false)
}
watch(
// 这种写法会侦听到 props 中 test 的变化
() => props.modelValue,
(newValue) => {
// 打开了
if (newValue === true) {
emits('open', '随便传个参数吧1')
}
// 关闭了
if (newValue === false) {
emits('close', '随便传个参数吧2')
}
}
)
</script>
<style scoped>
.box {
position: relative;
width: 500px;
height: 300px;
background-color: pink;
margin: auto;
}
.title {
text-align: center;
height: 30px;
background: skyblue;
}
.close {
display: block;
position: absolute;
top: 0;
right: 0;
width: 30px;
text-align: center;
line-height: 30px;
background-color: #ccc;
cursor: pointer;
}
.footer {
position: absolute;
bottom: 0;
right: 0;
}
</style>
原文链接:https://blog.csdn.net/qq_52845451/article/details/130233557
此处评论已关闭