vue3自己封装弹窗组件时,实现关闭弹窗遇到的问题解决方案
vue3封装弹窗组件,实现弹窗开关时遇到的v-model双向绑定问题
·
想实现一个弹窗组件
<scale-dialog></scale-dialog>
要实现打开和关闭弹窗功能,很自然地想到给弹窗加一个属性,通过父组件给子组件传值来控制是否显示弹窗:
<scale-dialog :show="show"></scale-dialog>
但是这种形式只能在父组件关闭弹窗,而弹窗组件本身肯定也要有一个关闭按钮,弹窗自己关闭自己的话这种方式就不太合适了。
最后参考element ui,使用v-model实现。
在vue2版本中,v-model本质上是父组件绑定value属性(v-bind:value)并监听input事件,子组件触发input事件从而反向更改value值的语法糖,所以本人理所当然地如下实现弹窗组件:
<template>
<div class="scale-dialog" :class="{sdShow: visiable, sdHide: !visiable}">
<div class="scale-dialog-inner">
<div class="scale-dialog-content" :style="{width, height}">
<div class="sd-header">
<div class="sd-title">
<slot name="title">对话框</slot>
</div>
<div class="sd-close" @click="visiable = false"></div>
</div>
<div class="sd-body">
<slot name="body"></slot>
</div>
<div class="sd-footer">
<slot name="footer"></slot>
</div>
</div>
</div>
<div class="scale-dialog-modal"></div>
</div>
</template>
<script setup>
import { defineProps, computed } from 'vue'
// 监听input事件
const emit = defineEmits(['input'])
const props = defineProps({
value: {
type: Boolean,
default: false,
required: true
},
width: {
type: String,
default: '144rem'
},
height: {
type: String,
default: 'auto'
}
})
// 通过visiable变量控制是否显示弹窗
const visiable = computed({
get() {
return props.value
},
set( newVal ) {
// 触发input事件,更改父组件的value值
emit('input', newVal)
}
})
</script>
然后啪啪打脸,实际上点击弹窗没有任何效果。
这是因为vue3中更改了v-model的实现原理,把v-bind:value改成了v-bind:modelValue,监听的事件也从input改成了update:modelValue,所以应该改成如下方式实现:
<template>
<div class="scale-dialog" :class="{sdShow: visiable, sdHide: !visiable}">
<div class="scale-dialog-inner">
<div class="scale-dialog-content" :style="{width, height}">
<div class="sd-header">
<div class="sd-title">
<slot name="title">对话框</slot>
</div>
<div class="sd-close" @click="visiable = false"></div>
</div>
<div class="sd-body">
<slot name="body"></slot>
</div>
<div class="sd-footer">
<slot name="footer"></slot>
</div>
</div>
</div>
<div class="scale-dialog-modal"></div>
</div>
</template>
<script setup>
import { ref, defineProps, computed } from 'vue'
const emit = defineEmits(['update:modelValue'])
const props = defineProps({
modelValue: {
type: Boolean,
default: false,
required: true
},
width: {
type: String,
default: '144rem'
},
height: {
type: String,
default: 'auto'
}
})
const visiable = computed({
get() {
return props.modelValue
},
set( newVal ) {
emit('update:modelValue', newVal)
}
})
</script>
出现这个问题实际上还是vue3文档没有掌握好,还需继续努力。
更多推荐
已为社区贡献1条内容
所有评论(0)