gtsoft-snail-job-admin/src/components/common/operate-drawer.vue
2024-04-19 17:41:21 +08:00

104 lines
2.5 KiB
Vue

<script setup lang="ts">
import { computed, nextTick, onUnmounted, reactive, ref, watch } from 'vue';
import { useAppStore } from '@/store/modules/app';
defineOptions({
name: 'OperateDrawer'
});
interface Props {
title?: string;
modelValue?: boolean;
}
const props = defineProps<Props>();
interface Emits {
(e: 'update:modelValue', modelValue: boolean): void;
}
const emit = defineEmits<Emits>();
const appStore = useAppStore();
const state = reactive({ width: 0 });
const visible = ref(props.modelValue);
const isFullscreen = ref(false);
const drawerWidth = computed(() => {
const maxMinWidth = 360;
const maxMaxWidth = 600;
if (appStore.isMobile) {
return state.width * 0.9 >= maxMinWidth ? `${maxMinWidth}px` : '90%';
}
let minWidth = state.width * 0.3 >= maxMinWidth ? `${maxMinWidth}px` : '30%';
minWidth = state.width <= 420 ? '90%' : minWidth;
let maxWidth = state.width * 0.5 >= maxMaxWidth ? `${maxMaxWidth}px` : '50%';
maxWidth = state.width <= 420 ? '90%' : maxWidth;
return isFullscreen.value ? maxWidth : minWidth;
});
const getState = () => {
state.width = document.documentElement.clientWidth;
};
nextTick(() => {
getState();
window.addEventListener('resize', getState);
});
onUnmounted(() => {
// 移除监听事件
window.removeEventListener('resize', getState);
});
watch(
() => props.modelValue,
val => {
visible.value = val;
},
{ immediate: true }
);
const onUpdateShow = (value: boolean) => {
emit('update:modelValue', value);
};
</script>
<template>
<NDrawer v-model:show="visible" display-directive="if" :width="drawerWidth" @update:show="onUpdateShow">
<NDrawerContent :title="props.title" :native-scrollbar="false" closable header-class="operate-dawer-header">
<template #header>
{{ props.title }}
<div
v-if="!appStore.isMobile && state.width <= 1920"
quaternary
class="fullscreen text-18px color-#6a6a6a"
@click="isFullscreen = !isFullscreen"
>
<icon-material-symbols:close-fullscreen-rounded v-if="isFullscreen" />
<icon-material-symbols:open-in-full-rounded v-else />
</div>
</template>
<slot></slot>
<template #footer>
<slot name="footer"></slot>
</template>
</NDrawerContent>
</NDrawer>
</template>
<style scoped>
.fullscreen {
height: 22px;
width: 22px;
display: flex;
justify-content: center;
align-items: center;
}
.fullscreen:hover {
background-color: #e8e8e8;
color: #696969;
border-radius: 6px;
cursor: pointer;
}
</style>