重构VirtualPage,所有miaoDirectory以插件形式使用

This commit is contained in:
539943419 committed 2024-08-14 01:43:24 +08:00
1 parent 8830e1aa3c
commit 0c501c800b
6 files changed
+399 -286

No files matched your search

+4 -3
View File
@@ -1,7 +1,8 @@
todo: 标签页,miaoDirectory切换动画 [finish] todo: 标签页,miaoDirectory切换动画 [finish]
todo: 重构virtualPage,所有page以插件形式使用 [] todo: 重构virtualPage,所有page以插件形式使用 [finish]
todo: miaoDirectory插件化,为后续插件功能开发做准备 [] todo: miaoDirectory插件化,为后续插件功能开发做准备 [finish]
todo: miaoPopupInput, 弹出一个输入框 todo: miaoPopupInput, 弹出一个输入框
todo: miaoDirectory的新建文件/文件夹功能 todo: miaoDirectory的新建文件/文件夹功能
todo: miaoDirectory的重命名功能 todo: miaoDirectory的重命名功能
todo: miaoDirectory的多选功能 todo: miaoDirectory的多选功能
todo: VirtualDirectory更新时更新文件信息
+11 -11
View File
@@ -5,7 +5,7 @@ import { NIcon, NScrollbar, NDropdown, NQrCode } from 'naive-ui';
import { EyeOffOutline, EyeOutline, CloseOutline, CopyOutline, EllipsisVertical, QrCodeOutline } from '@vicons/ionicons5' import { EyeOffOutline, EyeOutline, CloseOutline, CopyOutline, EllipsisVertical, QrCodeOutline } from '@vicons/ionicons5'
import miaoDirectory from './views/miaoDirectory.vue'; import miaoDirectory from './views/miaoDirectory.vue';
import VirtualPage from './class/VirtualPage'; import VirtualPage from './class/VirtualPage';
import VirtualDirectory from './class/VirtualDirectory'; import VirtualDirectory, { VirtualFile } from './class/VirtualDirectory';
import MiaoMask from './components/miaoMask.vue'; import MiaoMask from './components/miaoMask.vue';
import config from './config'; import config from './config';
import useViretualPages from './hooks/useVirtualPages'; import useViretualPages from './hooks/useVirtualPages';
@@ -31,16 +31,16 @@ const rootDirectory = reactive(new VirtualDirectory({
} }
})) }))
const createView = (initDirectory: VirtualDirectory, index?: number) => { // component就是一个vue组件,类似于miaoDirectory
const createView = (component: any, currentObjects: (VirtualDirectory | VirtualFile)[], index?: number) => {
index ?? (index = views.length) index ?? (index = views.length)
console.log(initDirectory) views.splice(index, 0, reactive<VirtualPage>(new VirtualPage(component, [...currentObjects])))
views.splice(index, 0, reactive<VirtualPage>(new VirtualPage(initDirectory)))
} }
const deleteView = (index: number) => { const deleteView = (index: number) => {
views.splice(index, 1) views.splice(index, 1)
if (views.length === 0) { if (views.length === 0) {
createView(rootDirectory) createView(miaoDirectory, [rootDirectory])
} }
} }
@@ -78,7 +78,6 @@ const openMenuOption = [
] ]
const handleMenuSelect = (key: string) => { const handleMenuSelect = (key: string) => {
console.log(key)
if (key === 'share') { if (key === 'share') {
showModal.value = true showModal.value = true
modalData.value = { modalData.value = {
@@ -93,7 +92,7 @@ const handleMenuSelect = (key: string) => {
} }
onMounted(() => { onMounted(() => {
createView(rootDirectory) createView(miaoDirectory, [rootDirectory])
}) })
</script> </script>
@@ -111,7 +110,8 @@ onMounted(() => {
<EyeOutline v-show="view.visible" class="icon-inner" /> <EyeOutline v-show="view.visible" class="icon-inner" />
<EyeOffOutline v-show="!view.visible" class="icon-inner" /> <EyeOffOutline v-show="!view.visible" class="icon-inner" />
</n-icon> </n-icon>
<n-icon class="tag-control-icon icon" @click="createView(view.currentDirectory, index + 1)"> <n-icon class="tag-control-icon icon"
@click="createView(view.component, view.currentObjects, index + 1)">
<CopyOutline /> <CopyOutline />
</n-icon> </n-icon>
<n-icon class="tag-control-icon icon" @click="deleteView(index)"> <n-icon class="tag-control-icon icon" @click="deleteView(index)">
@@ -135,8 +135,8 @@ onMounted(() => {
<div class="view-container"> <div class="view-container">
<transition-group name="page"> <transition-group name="page">
<div class="view-container-item" v-for="(view, index) of views" v-show="view.visible" :key="view.uid"> <div class="view-container-item" v-for="(view, index) of views" v-show="view.visible" :key="view.uid">
<miao-directory v-model:current-directory="view.currentDirectory" :color="view.color" :index="index" <component :is="view.component" v-model:current-objects="view.currentObjects" :id="view.uid"
@exit="deleteView(index)"></miao-directory> :color="view.color" @exit="deleteView(index)"></component>
</div> </div>
</transition-group> </transition-group>
</div> </div>
@@ -327,7 +327,7 @@ $tag-width: 170px;
// transition: all 0.2s ease; // transition: all 0.2s ease;
// } // }
// .page-enter-active { // .page-enter-active {
// } // }
+24 -14
View File
@@ -1,35 +1,50 @@
import VirtualDirectory from "./VirtualDirectory"; import { shallowRef } from "vue";
import VirtualDirectory, { VirtualFile } from "./VirtualDirectory";
import generateId from "@/hooks/generateId"; import generateId from "@/hooks/generateId";
const getRandomWebSafeColor = (() => { const getRandomWebSafeColor = (() => {
const webSafeColors = ["#009900", "#999900", "#009999", "#990099", "#0000ee"]; const webSafeColors = ["#009900", "#999900", "#009999", "#990099", "#0000ee"];
let counter = 0 let counter = 0;
return () => { return () => {
const color = webSafeColors[counter % webSafeColors.length] const color = webSafeColors[counter % webSafeColors.length];
counter += 1 counter += 1;
return color; return color;
}; };
})(); })();
export default class VirtualPage { export default class VirtualPage {
constructor(initDirectory: VirtualDirectory) { constructor(component: any, initObjects: (VirtualDirectory | VirtualFile)[]) {
this.component = shallowRef(component);
this.currentObjects = initObjects;
this.visible = true; this.visible = true;
this.uid = generateId(); this.uid = generateId();
this.currentDirectory = initDirectory;
this.refreshKey = Math.random(); this.refreshKey = Math.random();
this.color = getRandomWebSafeColor(); this.color = getRandomWebSafeColor();
} }
component: any;
// 是否可见
visible: boolean; visible: boolean;
currentDirectory: VirtualDirectory; // 当前正在使用的文件或是文件夹
currentObjects: (VirtualDirectory | VirtualFile)[];
// 区分每一个页面的唯一id // 区分每一个页面的唯一id
uid: number; uid: number;
// 当refreshKey改变时需要刷新页面,目前还没接入刷新 // 当refreshKey改变时需要刷新页面,目前还没接入刷新
refreshKey: number; refreshKey: number;
// 为了区分,每个虚拟页面都会分配一个color,这个color会体现在tab上
color: string; color: string;
// 用于展示的title
_title?: string;
get title() { get title() {
return this.currentDirectory.name; if (this._title) {
return this._title;
}
return this.currentObjects[0].name;
}
setTitle(title: string) {
this._title = title;
} }
// 切换显示状态 // 切换显示状态
@@ -37,11 +52,6 @@ export default class VirtualPage {
this.visible = !this.visible; this.visible = !this.visible;
} }
// 设置(同步)正在展示的文件夹
setCurrrentDirectory(currDir: VirtualDirectory) {
this.currentDirectory = currDir;
}
// 刷新,不过好像没有用得到的时候吧 // 刷新,不过好像没有用得到的时候吧
// 事实上也不应该用得到,因为更新应该是响应式的 // 事实上也不应该用得到,因为更新应该是响应式的
refresh() { refresh() {
@@ -34,6 +34,7 @@ const dataBus = useDataBus()
const emit = defineEmits<{ const emit = defineEmits<{
download: [] download: []
delete: [] delete: []
dragStart: []
}>() }>()
const props = defineProps<{ const props = defineProps<{
+43
View File
@@ -0,0 +1,43 @@
<template>
<miao-mask v-model:show="showMask">
<n-card title="">
<n-input v-model:value="inputValue" type="text" placeholder="基本的 Input" />
<n-button @click="_resolve && _resolve(inputValue)">确认</n-button>
</n-card>
</miao-mask>
</template>
<script lang="ts" setup>
import { reactive, ref } from "vue";
import { NCard, NInput, NButton } from "naive-ui";
import miaoMask from "./miaoMask.vue";
const showMask = ref(true);
const inputValue = ref<string>("");
const _resolve = ref<(text: string) => void>()
type popupConfig = {
title: string
placeholder: string
options: {
label
}
}
const _config = reactive<popupConfig>({
title: '',
placeholder: ''
})
const popup = () => {
showMask.value = true
return new Promise((resolve: (text: string) => void) => { _resolve.value = resolve }).then((text: string) => {
showMask.value = false
return text;
});
};
defineExpose({ popup });
</script>
<style scoped lang="scss"></style>
+316 -258
View File
@@ -1,186 +1,240 @@
<template> <template>
<div class="miao-directory-item-container" ref="rootDomRef"> <div class="miao-directory-item-container" ref="rootDomRef">
<div class="container-top" :style="{ backgroundColor: props.index % 2 === 0 ? '#f8f8f8' : 'rgb(240 240 240)' }"> <div
<div class="container-top-colorbar" :style="{ backgroundColor: props.color }"></div> class="container-top"
<div class="container-top-breadcrumb"> :style="{ backgroundColor: index % 2 === 0 ? '#f8f8f8' : 'rgb(240 240 240)' }"
<!-- <n-scrollbar x-scrollable> --> >
<div class="container-top-breadcrumb-container"> <div class="container-top-colorbar" :style="{ backgroundColor: props.color }"></div>
<n-breadcrumb separator=">" style="margin-left: 5px;"> <div class="container-top-breadcrumb">
<n-breadcrumb-item :clickable="false"> <!-- <n-scrollbar x-scrollable> -->
<n-icon size="18"> <div class="container-top-breadcrumb-container">
<CloudOutline /> <n-breadcrumb separator=">" style="margin-left: 5px">
</n-icon> <n-breadcrumb-item :clickable="false">
</n-breadcrumb-item> <n-icon size="18">
<n-breadcrumb-item v-for="(dir) in currentDirectory?.directoryArray" <CloudOutline />
@click="setCurrentDirectory(dir)" :clickable="true"> </n-icon>
<div>{{ dir.name }}</div> </n-breadcrumb-item>
</n-breadcrumb-item> <n-breadcrumb-item
</n-breadcrumb> v-for="dir in currentDirectory?.directoryArray"
</div> @click="setCurrentDirectory(dir)"
<!-- </n-scrollbar> --> :clickable="true"
</div> >
<div class="container-top-tools"> <div>{{ dir.name }}</div>
<n-icon class="container-top-tools-item" size="15" @click="handleBack"> </n-breadcrumb-item>
<ChevronBackOutline /> </n-breadcrumb>
</n-icon>
<n-icon class="container-top-tools-item" size="14" @click="handleReload">
<ReloadOutline class="container-top-tools-item-reload" />
</n-icon>
<n-icon class="container-top-tools-item" size="20" @click="emit('exit')">
<CloseOutline />
</n-icon>
</div>
</div> </div>
<div class="container-items" <!-- </n-scrollbar> -->
:style="{ backgroundColor: props.index % 2 === 0 ? '#f8f8f8' : 'rgb(240 240 240)' }"> </div>
<n-scrollbar> <div class="container-top-tools">
<transition-group name="dirItem"> <n-icon class="container-top-tools-item" size="15" @click="handleBack">
<miaoDirectoryItem v-for="(dir) in showData_directory" @click="setCurrentDirectory(dir)" :item="dir" <ChevronBackOutline />
:key="dir.uid" :color="props.color" @delete="handleItemDelete(dir)" /> </n-icon>
</transition-group> <n-icon class="container-top-tools-item" size="14" @click="handleReload">
<transition-group name="dirItem"> <ReloadOutline class="container-top-tools-item-reload" />
<miaoDirectoryItem v-for="(file) in showData_files" :item="file" :key="file.uid" </n-icon>
@click="openUrl(`${baseUrl}${api.get}${file.path}`)" <n-icon class="container-top-tools-item" size="20" @click="emit('exit')">
@download="openUrl(`${baseUrl}${api.get}${file.path}`, { download: file.name })" <CloseOutline />
@delete="handleItemDelete(file)" :color="props.color" /> </n-icon>
</transition-group> </div>
</n-scrollbar>
</div>
<div class="container-bottom"
:style="{ backgroundColor: props.index % 2 === 1 ? 'rgb(61 61 61)' : 'rgb(162 162 162)' }"></div>
<miaoMask v-model:show="showModel"></miaoMask>
</div> </div>
<div
class="container-items"
:style="{ backgroundColor: index % 2 === 0 ? '#f8f8f8' : 'rgb(240 240 240)' }"
>
<n-scrollbar>
<transition-group name="dirItem">
<miaoDirectoryItem
v-for="dir in showData_directory"
@click="setCurrentDirectory(dir)"
:item="dir"
:key="dir.uid"
:color="props.color"
@delete="handleItemDelete(dir)"
/>
</transition-group>
<transition-group name="dirItem">
<miaoDirectoryItem
v-for="file in showData_files"
:item="file"
:key="file.uid"
@click="openUrl(`${baseUrl}${api.get}${file.path}`)"
@download="
openUrl(`${baseUrl}${api.get}${file.path}`, { download: file.name })
"
@delete="handleItemDelete(file)"
:color="props.color"
/>
</transition-group>
</n-scrollbar>
</div>
<div
class="container-bottom"
:style="{ backgroundColor: index % 2 === 1 ? 'rgb(61 61 61)' : 'rgb(162 162 162)' }"
></div>
<miao-mask v-model:show="showModel"></miao-mask>
<!-- <miao-popup-input ref="popupInput"></miao-popup-input> -->
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { NBreadcrumbItem, NBreadcrumb, NIcon, NScrollbar } from "naive-ui";
import type { file, directory } from "@/types/type.ts";
import VirtualDirectory, { VirtualFile } from "@/class/VirtualDirectory";
import { computed, onMounted, ref } from "vue";
import Config from "@/config";
import dropHandler, { dropHandlerHooks } from "@/hooks/dropHandler";
import miaoMask from "@/components/miaoMask.vue";
import miaoPopupInput from "@/components/miaoPopupInput.vue";
import miaoDirectoryItem from "@/components/miaoDirectory/miaoDirectoryItem.vue";
import useMiaoFetchApi from "@/hooks/useMiaoFetchApi";
import useDataBus from "@/hooks/useDataBus";
import {
CloudOutline,
ChevronBackOutline,
ReloadOutline,
CloseOutline,
} from "@vicons/ionicons5";
import useUploadQueue from "@/hooks/useUploadQueue";
import useViretualPages from "@/hooks/useVirtualPages";
import { NBreadcrumbItem, NBreadcrumb, NIcon, NScrollbar } from 'naive-ui' const { baseUrl, api } = Config;
import type { file, directory } from '@/types/type.ts' const dataBus = useDataBus();
import VirtualDirectory, { VirtualFile } from '@/class/VirtualDirectory'; const views = useViretualPages();
import { computed, onMounted, ref } from 'vue';
import Config from '@/config'
import dropHandler, { dropHandlerHooks } from '@/hooks/dropHandler';
import miaoMask from '@/components/miaoMask.vue';
import miaoDirectoryItem from '@/components/miaoDirectory/miaoDirectoryItem.vue';
import useMiaoFetchApi from '@/hooks/useMiaoFetchApi';
import useDataBus from '@/hooks/useDataBus';
import { CloudOutline, ChevronBackOutline, ReloadOutline, CloseOutline } from '@vicons/ionicons5'
import useUploadQueue from '@/hooks/useUploadQueue';
const { baseUrl, api } = Config const miaoFetchApi = useMiaoFetchApi();
const dataBus = useDataBus()
const miaoFetchApi = useMiaoFetchApi()
const props = defineProps<{ const props = defineProps<{
color: string color: string;
index: number id: number;
}>() }>();
const emit = defineEmits<{ const emit = defineEmits<{
exit: [] exit: [];
}>() }>();
const popupInput = ref()
// 是否显示模态框 // 是否显示模态框
const showModel = ref(0) const showModel = ref(0);
const currentObjects = defineModel<VirtualDirectory[]>("currentObjects", {
required: true,
});
// 目前展示的Dir // 目前展示的Dir
const currentDirectory = defineModel<VirtualDirectory>('currentDirectory', { required: true }) const currentDirectory = computed(() => {
return currentObjects.value[0];
});
const index = computed(() => {
for (let i in views) {
if (views[i].uid === props.id) {
return parseInt(i);
}
}
return 0;
});
// 用于展示的数据,后续会增加排序等操作 // 用于展示的数据,后续会增加排序等操作
const showData_directory = computed<VirtualDirectory[]>(() => { const showData_directory = computed<VirtualDirectory[]>(() => {
const data = currentDirectory.value?.directorys ? [...currentDirectory.value?.directorys] : [] const data = currentDirectory.value?.directorys
return data ? [...currentDirectory.value?.directorys]
}) : [];
return data;
});
const showData_files = computed<VirtualFile[]>(() => { const showData_files = computed<VirtualFile[]>(() => {
const data = currentDirectory.value?.files ? [...currentDirectory.value?.files] : [] const data = currentDirectory.value?.files ? [...currentDirectory.value?.files] : [];
return data return data;
}) });
// 用于监听拖拽文件事件 // 用于监听拖拽文件事件
const rootDomRef = ref<HTMLDivElement>() const rootDomRef = ref<HTMLDivElement>();
const uploadQueue = useUploadQueue() const uploadQueue = useUploadQueue();
// 设置显示的dir // 设置显示的dir
const setCurrentDirectory = async (virtualDirectory: VirtualDirectory) => { const setCurrentDirectory = async (virtualDirectory: VirtualDirectory) => {
// 若没有缓存数据则同步刷新,有缓存数据则异步刷新 // 若没有缓存数据则同步刷新,有缓存数据则异步刷新
if (virtualDirectory.files === undefined || virtualDirectory.directorys === undefined) { if (virtualDirectory.files === undefined || virtualDirectory.directorys === undefined) {
const data: (file | directory)[] = await miaoFetchApi.get(virtualDirectory) const data: (file | directory)[] = await miaoFetchApi.get(virtualDirectory);
virtualDirectory.updateContent(data) virtualDirectory.updateContent(data);
} else { } else {
; (async () => { (async () => {
const data: (file | directory)[] = await miaoFetchApi.get(virtualDirectory) const data: (file | directory)[] = await miaoFetchApi.get(virtualDirectory);
virtualDirectory.updateContent(data) virtualDirectory.updateContent(data);
})() })();
} }
currentDirectory.value = virtualDirectory currentObjects.value[0] = virtualDirectory;
} };
const reload = () => { const reload = () => {
setCurrentDirectory(currentDirectory.value) setCurrentDirectory(currentDirectory.value);
} };
const openUrl = (href: string, config?: { const openUrl = (
download?: string href: string,
target?: string config?: {
}) => { download?: string;
let { target, download } = config ?? {} target?: string;
}
console.log({ target, download, href }) ) => {
const a = document.createElement('a'); let { target, download } = config ?? {};
a.setAttribute('href', href); const a = document.createElement("a");
a.setAttribute('target', target ?? '_blank') a.setAttribute("href", href);
download && a.setAttribute('download', download); a.setAttribute("target", target ?? "_blank");
a.click(); download && a.setAttribute("download", download);
} a.click();
};
const handleBack = () => { const handleBack = () => {
if (currentDirectory.value?.parent) { if (currentDirectory.value?.parent) {
setCurrentDirectory(currentDirectory.value.parent) setCurrentDirectory(currentDirectory.value.parent);
} }
} };
const handleReload = () => { const handleReload = () => {
reload() reload();
} };
const handleItemDelete = async (item: VirtualDirectory | VirtualFile) => { const handleItemDelete = async (item: VirtualDirectory | VirtualFile) => {
const { response } = miaoFetchApi.delete(item, { const { response } = miaoFetchApi.delete(item, {
retry: 5 retry: 5,
}) });
// todo: 将删除事件统一用一个事件管理中心管理 // todo: 将删除事件统一用一个事件管理中心管理
const id = (await response).eventId const id = (await response).eventId;
const { response: res } = miaoFetchApi.query(id) const { response: res } = miaoFetchApi.query(id);
const eventResult = await res const eventResult = await res;
if (eventResult.status === 'success') { if (eventResult.status === "success") {
reload() reload();
} }
} };
onMounted(async () => { onMounted(async () => {
currentDirectory.value && await setCurrentDirectory(currentDirectory.value) await setCurrentDirectory(currentDirectory.value);
// 拖动事件处理 // 拖动事件处理
const dropFileOption: dropHandlerHooks = { const dropFileOption: dropHandlerHooks = {
onDropFiles(files: File[]) { onDropFiles(files: File[]) {
const dragData = dataBus.pop('dragData') const dragData = dataBus.pop("dragData");
console.log({ dragData, files }) console.log({ dragData, files });
if (files && files.length > 0) { if (files && files.length > 0) {
currentDirectory.value && uploadQueue.push(files, currentDirectory.value, { currentDirectory.value &&
onFinish() { uploadQueue.push(files, currentDirectory.value, {
reload() onFinish() {
}, reload();
}) },
} });
}, }
onEnter() { },
showModel.value += 1 onEnter() {
}, showModel.value += 1;
onEnd() { },
showModel.value -= 1 onEnd() {
}, showModel.value -= 1;
} },
rootDomRef.value && dropHandler(rootDomRef.value, dropFileOption) };
}) rootDomRef.value && dropHandler(rootDomRef.value, dropFileOption);
console.log(await popupInput.value.popup())
});
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@@ -188,133 +242,137 @@ $top-height: 30px;
$bottom-bar-height: 60px; $bottom-bar-height: 60px;
.miao-directory-item-container { .miao-directory-item-container {
position: relative;
height: 100%;
width: inherit;
min-width: 266px;
display: flex;
flex-direction: column;
overflow: hidden;
.container-top {
height: $top-height;
width: 100%;
user-select: none;
position: relative; position: relative;
height: 100%;
width: inherit;
min-width: 266px;
display: flex; display: flex;
flex-direction: column; align-items: center;
overflow: hidden; overflow: hidden;
background-color: #f1f1f1;
.container-top { .container-top-colorbar {
height: $top-height; height: 70%;
width: 100%; width: 5px;
user-select: none; margin-left: 10px;
position: relative; border-radius: 3px 0 0 3px;
}
.container-top-breadcrumb {
position: relative;
height: 70%;
width: calc(100% - 95px);
display: flex;
justify-content: flex-start;
align-items: center;
// overflow: hidden;
overflow-y: hidden;
overflow-x: hidden;
background-color: #ffffff;
padding: 0 5px;
border-radius: 0 3px 3px 0;
.container-top-breadcrumb-container {
position: absolute;
height: 100%;
right: 0;
top: 0;
min-width: 100%;
display: flex; display: flex;
justify-content: flex-start;
align-items: center; align-items: center;
overflow: hidden; }
background-color: #f1f1f1;
.container-top-colorbar {
height: 70%;
width: 5px;
margin-left: 10px;
border-radius: 3px 0 0 3px;
}
.container-top-breadcrumb {
position: relative;
height: 70%;
width: calc(100% - 95px);
display: flex;
justify-content: flex-start;
align-items: center;
// overflow: hidden;
overflow-y: hidden;
overflow-x: hidden;
background-color: #ffffff;
padding: 0 5px;
border-radius: 0 3px 3px 0;
.container-top-breadcrumb-container {
position: absolute;
height: 100%;
right: 0;
top: 0;
min-width: 100%;
display: flex;
justify-content: flex-start;
align-items: center;
}
}
.container-top-tools {
position: relative;
height: 100%;
width: 70px;
padding: 0 5px;
display: flex;
justify-content: space-around;
align-items: center;
.container-top-tools-item {
width: 20px;
height: 20px;
display: flex;
justify-content: center;
align-items: center;
background-color: #ffffff00;
border-radius: 5px;
transition: background-color 0.3s;
cursor: pointer;
.container-top-tools-item-reload {
transition: transform 0.6s ease-in-out;
}
&:hover {
background-color: rgba(128, 128, 128, 0.4);
}
&:active .container-top-tools-item-reload {
transform: rotate(360deg);
}
}
// &::after {
// content: '';
// height: 60%;
// position: absolute;
// right: -2px;
// width: 2px;
// background-color: #828282;
// }
}
} }
.container-items { .container-top-tools {
width: 100%; position: relative;
height: calc(100% - $top-height - $bottom-bar-height); height: 100%;
// flex: 1; width: 70px;
} padding: 0 5px;
display: flex;
justify-content: space-around;
align-items: center;
.container-bottom { .container-top-tools-item {
height: $bottom-bar-height; width: 20px;
background-color: bisque; height: 20px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
user-select: none; background-color: #ffffff00;
box-shadow: 0px 1px 10px #888888; border-radius: 5px;
z-index: 2; transition: background-color 0.3s;
cursor: pointer;
.container-top-tools-item-reload {
transition: transform 0.6s ease-in-out;
}
&:hover {
background-color: rgba(128, 128, 128, 0.4);
}
&:active .container-top-tools-item-reload {
transform: rotate(360deg);
}
}
// &::after {
// content: '';
// height: 60%;
// position: absolute;
// right: -2px;
// width: 2px;
// background-color: #828282;
// }
} }
}
.container-items {
width: 100%;
height: calc(100% - $top-height - $bottom-bar-height);
// flex: 1;
}
.container-bottom {
height: $bottom-bar-height;
background-color: bisque;
display: flex;
justify-content: center;
align-items: center;
user-select: none;
box-shadow: 0px 1px 10px #888888;
z-index: 2;
}
} }
// transition动画相关 // transition动画相关
.miao-directory-item-container { .miao-directory-item-container {
.container-items { .container-items {
.dirItem-move { .dirItem-move {
transition: all 0.2s ease; transition: all 0.2s ease;
}
.dirItem-leave-active {
transition: none;
}
.dirItem-enter-from {
opacity: 0;
}
.dirItem-leave-active {
position: absolute;
}
} }
.dirItem-leave-active {
transition: none;
}
.dirItem-enter-from {
opacity: 0;
}
.dirItem-leave-active {
position: absolute;
}
}
} }
</style> </style>