104 lines
2.5 KiB
Vue
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>
|