fix(editor): 修改pagebar过长无法滚动问题

This commit is contained in:
roymondchen 2022-04-02 16:36:42 +08:00 committed by jia000
parent a842c5b0ce
commit 9b849cc906
2 changed files with 117 additions and 12 deletions

View File

@ -1,9 +1,12 @@
<template>
<div class="m-editor-page-bar">
<div class="m-editor-page-bar-item" @click="addPage">
<el-icon class="m-editor-page-bar-menu-add-icon"><plus></plus></el-icon>
<div class="m-editor-page-bar" ref="pageBar">
<div class="m-editor-page-bar-item m-editor-page-bar-item-icon" @click="addPage">
<el-icon><plus></plus></el-icon>
</div>
<template v-if="root">
<div v-if="canScroll" class="m-editor-page-bar-item m-editor-page-bar-item-icon" @click="scroll('left')">
<el-icon><arrow-left-bold></arrow-left-bold></el-icon>
</div>
<div v-if="root" class="m-editor-page-bar-items" ref="itemsContainer" :style="`width: ${itemsContainerWidth}px`">
<div
v-for="item in root.items"
:key="item.key"
@ -33,29 +36,120 @@
</template>
</el-popover>
</div>
</template>
</div>
<div v-if="canScroll" class="m-editor-page-bar-item m-editor-page-bar-item-icon" @click="scroll('right')">
<el-icon><arrow-right-bold></arrow-right-bold></el-icon>
</div>
</div>
</template>
<script lang="ts">
import { computed, defineComponent, inject, toRaw } from 'vue';
import { CaretBottom, Plus } from '@element-plus/icons';
import { computed, ComputedRef, defineComponent, inject, onMounted, onUnmounted, ref, toRaw, watch } from 'vue';
import { ArrowLeftBold, ArrowRightBold, CaretBottom, Plus } from '@element-plus/icons';
import type { MPage } from '@tmagic/schema';
import type { MApp, MPage } from '@tmagic/schema';
import { NodeType } from '@tmagic/schema';
import type { Services } from '@editor/type';
import { generatePageNameByApp } from '@editor/utils/editor';
const useScroll = (root: ComputedRef<MApp | undefined>) => {
const pageBar = ref<HTMLDivElement>();
const itemsContainer = ref<HTMLDivElement>();
const pageBarWidth = ref(0);
const canScroll = ref(false);
const itemsContainerWidth = computed(() => pageBarWidth.value - 105);
let translateLeft = 0;
const resizeObserver = new ResizeObserver((entries) => {
for (const { contentRect } of entries) {
const { width } = contentRect;
pageBarWidth.value = width || 0;
setCanScroll();
}
});
const setCanScroll = () => {
if (itemsContainer.value) {
canScroll.value = itemsContainer.value.scrollWidth > pageBarWidth.value - 105;
}
};
const scroll = (type: 'left' | 'right' | 'start' | 'end') => {
if (!itemsContainer.value) return;
const maxScrollLeft = itemsContainer.value.scrollWidth - itemsContainerWidth.value;
if (type === 'left') {
translateLeft += 100;
if (translateLeft > 0) {
translateLeft = 0;
}
} else if (type === 'right') {
translateLeft -= 100;
if (-translateLeft > maxScrollLeft) {
translateLeft = -maxScrollLeft;
}
} else if (type === 'start') {
translateLeft = 0;
} else if (type === 'end') {
translateLeft = -maxScrollLeft;
}
itemsContainer.value.style.transform = `translate(${translateLeft}px, 0px)`;
};
onMounted(() => {
pageBar.value && resizeObserver.observe(pageBar.value);
});
onUnmounted(() => {
resizeObserver.disconnect();
});
watch(
() => root.value?.items.length,
(length = 0, preLength = 0) => {
setTimeout(() => {
setCanScroll();
if (length < preLength) {
scroll('start');
} else {
scroll('end');
}
});
},
);
return {
pageBar,
itemsContainer,
canScroll,
itemsContainerWidth,
scroll,
};
};
export default defineComponent({
components: { CaretBottom, Plus },
components: { ArrowLeftBold, ArrowRightBold, CaretBottom, Plus },
setup() {
const services = inject<Services>('services');
const editorService = services?.editorService;
const root = computed(() => editorService?.get<MApp>('root'));
return {
root: computed(() => editorService?.get('root')),
...useScroll(root),
root,
page: computed(() => editorService?.get('page')),
switchPage(page: MPage) {

View File

@ -6,19 +6,25 @@
width: 100%;
height: $--page-bar-height;
line-height: $--page-bar-height;
background-color: #f3f3f3;
color: $--font-color;
background-color: #f3f3f3;
border-top: 1px solid $--border-color;
z-index: 2;
overflow: hidden;
.m-editor-page-bar-item {
&-items {
display: flex;
transition: transform 0.3s;
}
&-item {
padding: 0 10px;
cursor: pointer;
border-right: 1px solid $--border-color;
display: flex;
justify-items: center;
align-items: center;
background-color: #f3f3f3;
&.active {
background-color: #fff;
@ -29,6 +35,11 @@
}
}
&-icon {
position: relative;
z-index: 1;
}
.m-editor-page-bar-title {
max-width: 150px;
text-overflow: ellipsis;