目的
对Dialog弹框进行二次封装,减少冗余代码。
首先
使用element-ui 搭建dialog弹框,只显示确定和取消两个按钮
设定内容区域的插槽
对外暴露visible属性,用于显示隐藏弹框
通过计算属性,对.sync进行转换,外部也可以直接使用visible.sync
对外暴露取消事件和确定事件
通过v-on = $listeners触发父组件的事件
把inheritAttrs设置为false
通过v-bind=$attrs让父组件绑定的实例属性生效
<template>
<el-dialog :visible.sync="visibleDialog" v-bind="$attrs" v-on="$listeners">
<!--内容区域的默认插槽-->
<slot />
<!--使用弹框的footer插槽添加按钮-->
<template #footer>
<!--对外继续暴露footer插槽,有个别弹框按钮需要自定义-->
<slot name="footer">
<!--将取消与确定按钮集成到内部-->
<el-row slot="footer" type="flex" justify="center">
<el-col :span="6">
<el-button type="primary" size="small" @click="$_handleConfirm">确定</el-button>
<el-button size="small" @click="$_handleCancel">取消</el-button>
</el-col>
</el-row>
</slot>
</template>
</el-dialog>
</template>
<script>
export default {
// 默认情况下父作用域的不被认作 props 的 attribute 绑定 (attribute bindings)
// 将会“回退”且作为普通的 HTML attribute 应用在子组件的根元素上。
// 通过设置 inheritAttrs 到 false,这些默认行为将会被去掉
inheritAttrs: false,
props: {
// 对外暴露visible属性,用于显示隐藏弹框
visible: {
type: Boolean,
default: false
}
},
computed: {
// 通过计算属性,对.sync进行转换,外部也可以直接使用visible.sync
visibleDialog: {
get() {
return this.visible
},
set(val) {
this.$emit('update:visible', val)
}
}
},
methods: {
// 对外抛出cancel事件
$_handleCancel() {
this.$emit('cancel')
},
// 对外抛出 confirm事件
$_handleConfirm() {
this.$emit('confirm')
}
}
}
</script>
实现原理:当子组件没有接受的父组件传过来的属性,默认是不会在根元素中显示的,当设置为false,这些默认行为将会被去掉,通过实例属性 $attrs 可以让这些特性生效,且可以通过 v-bind 显性的绑定到非根元素上