guns/guns-front-project/src/components/common/CommonDrawer/index.vue

252 lines
5.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<a-drawer v-bind="props" @close="close" @afterVisibleChange="afterVisibleChange" :width="isMobile ? 340 : props.width">
<!-- 抽屉右上角的操作区域 -->
<template #extra v-if="slots.extra">
<slot name="extra"></slot>
</template>
<!-- 抽屉的页脚 -->
<template #footer v-if="slots.footer">
<slot name="footer"></slot>
</template>
<!-- 抽屉的标题 -->
<template #title v-if="slots.title">
<slot name="title"></slot>
</template>
<!-- 自定义关闭图标 -->
<template #closeIcon v-if="slots.closeIcon">
<slot name="closeIcon"></slot>
</template>
<slot name="top"></slot>
<a-tabs v-model:activeKey="currentActive" v-if="isShowTab" @change="tabChange">
<a-tab-pane :key="tabItem.key" v-for="tabItem in tabList">
<template #tab>
<div class="tab-item">
<i :class="'iconfont icons ' + tabItem.icon" v-if="tabItem.icon"></i>
<div>{{ tabItem.name }}</div>
</div>
</template>
</a-tab-pane>
</a-tabs>
<!-- 内容 -->
<slot></slot>
<!-- 关闭按钮 -->
<div class="close-button" @click="close" v-if="visible"><close-outlined /></div>
</a-drawer>
</template>
<script setup name="CommonDrawer">
import { useSlots, watch, ref, inject } from 'vue';
import { LAYOUT_KEY, screenWidth } from '../../layout/util';
const slots = useSlots();
const props = defineProps({
//
visible: {
type: Boolean,
default: false
},
class: {
type: String,
default: 'drawer'
},
// Dom
autofocus: {
type: Boolean,
default: true
},
// Drawer
bodyStyle: {
type: Object,
default: {}
},
//
closable: {
type: Boolean,
default: false
},
// Drawer
contentWrapperStyle: {
type: Object,
default: {}
},
// Drawer
destroyOnClose: {
type: Boolean,
default: false
},
// Drawer
drawerStyle: {
type: Object,
default: {}
},
//
footerStyle: {
type: Object,
default: {}
},
// Drawer
forceRender: {
type: Boolean,
default: false
},
// Drawer HTML
getContainer: {
type: [String, Boolean],
default: false
},
// Drawer
headerStyle: {
type: Object,
default: {}
},
// , placement top bottom 使
height: {
type: [String, Number],
default: 378
},
// esc
keyboard: {
type: Boolean,
default: true
},
//
mask: {
type: Boolean,
default: false
},
//
maskClosable: {
type: Boolean,
default: false
},
//
maskStyle: {
type: Object,
default: {}
},
//
placement: {
type: String,
default: 'right'
},
// Drawer
push: {
type: [Boolean, Object],
default: { distance: 180 }
},
// default 378px large 736px
size: {
type: String,
default: 'default'
},
// Drawer
style: {
type: Object,
default: {}
},
//
width: {
type: [String, Number],
default: 378
},
// Drawer z-index
zIndex: {
type: Number,
default: 1000
},
// tab
activeKey: {
type: [String, Number],
default: '1'
},
// tab
isShowTab: {
type: Boolean,
default: false
},
// tab
tabList: {
type: Array,
default: []
}
});
const emit = defineEmits(['close', 'afterVisibleChange', 'tabChange']);
//
const currentActive = ref('1');
//
const layoutProvide = inject(LAYOUT_KEY, ref({ isMobile: screenWidth() < 768 }));
const isMobile = ref(false);
watch(
() => layoutProvide.value,
val => {
isMobile.value = val.isMobile;
},
{ deep: true, immediate: true }
);
// 关闭抽屉
const close = e => {
emit('close', e);
};
// 切换抽屉时动画结束后的回调
const afterVisibleChange = visible => {
emit('afterVisibleChange', visible);
};
// tab切换
const tabChange = key => {
emit('tabChange', key);
};
watch(
() => props.activeKey,
val => {
if (val) {
currentActive.value = val;
}
},
{ deep: true, immediate: true }
);
</script>
<style lang="less" scoped>
.close-button {
position: absolute;
left: -40px;
top: 180px;
width: 40px;
height: 40px;
font-size: 22px;
background: #6F9AE7;
text-align: center;
line-height: 40px;
cursor: pointer;
color: #fff;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
box-shadow: -2px 0px 4px 3px #0000001F;
}
:deep(.ant-drawer-content) {
overflow: visible;
}
.tab-item {
display: flex;
justify-content: center;
align-items: center;
}
.icons {
font-size: 20px;
margin-right: 5px;
}
:deep(.ant-drawer-wrapper-body) {
height: 100%;
}
</style>