Skip to content

Commit 9eb07dd

Browse files
committed
Update: 主题横向拖拽改变宽度
1 parent f850655 commit 9eb07dd

File tree

5 files changed

+126
-16
lines changed

5 files changed

+126
-16
lines changed

eslint.config.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import pluginVue from 'eslint-plugin-vue';
2-
import js from '@eslint/js'
3-
import ts from 'typescript-eslint'
2+
import js from '@eslint/js';
3+
import ts from 'typescript-eslint';
44

55
export default [
66
js.configs.recommended,
@@ -18,7 +18,7 @@ export default [
1818
// 允许any类型
1919
'@typescript-eslint/no-explicit-any': 'off',
2020
// 允许未使用的变量
21-
"@typescript-eslint/no-unused-expressions": "off",
21+
'@typescript-eslint/no-unused-expressions': 'off',
2222

2323
/** 空格 */
2424
// 数组括号前后的空格
@@ -52,11 +52,16 @@ export default [
5252

5353
/** 数组、对象对齐 */
5454
// 确保数组的多行格式对齐
55-
'array-bracket-newline': ['error', 'consistent'],
55+
'array-bracket-newline': [ 'error', 'consistent' ],
5656
// 确保数组元素的换行方式一致
57-
'array-element-newline': ['error', 'consistent'],
57+
'array-element-newline': [ 'error', 'consistent' ],
5858
// 确保对象的多行格式对齐
59-
'object-curly-newline': ['error', { multiline: true, consistent: true }],
59+
'object-curly-newline': [ 'error', { multiline: true, consistent: true } ],
60+
// 属性数量限制
61+
'vue/max-attributes-per-line': [ 'error', {
62+
'singleline': 4,
63+
'multiline': 1
64+
} ],
6065

6166
/** Vue风格 */
6267
// 设置 Vue 模版中 <template> 标签中的代码缩进为 4 个空格,有一层默认缩进

package/components/NanoBody/index.vue

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
11
<template>
2-
<div class="relative grow flex items-stretch min-h-0">
3-
<NanoLeftActionBar v-if="!ctl.hideLeftActionBar"/>
4-
<NanoLeftSidebar v-if="!ctl.hideLeftSidebar"/>
5-
<NanoMain/>
6-
<NanoRightSidebar v-if="!ctl.hideRightSidebar"/>
7-
<NanoRightActionBar v-if="!ctl.hideRightActionBar"/>
2+
<div ref="body" class="relative grow flex items-stretch min-h-0">
3+
<NanoLeftActionBar v-if="!ctl.hideLeftActionBar" ref="leftActionBar"/>
4+
<NanoLeftSidebar v-if="!ctl.hideLeftSidebar" ref="leftSidebar">
5+
<!--draggable line-->
6+
<div
7+
ref="leftDraggableLine"
8+
class="absolute z-2 right--1 top-0 h-full w-1 bg-transparent cursor-col-resize"
9+
/>
10+
</NanoLeftSidebar>
11+
<NanoMain ref="main"/>
12+
<NanoRightSidebar v-if="!ctl.hideRightSidebar" ref="rightSidebar">
13+
<!--draggable line-->
14+
<div
15+
ref="rightDraggableLine"
16+
class="absolute z-2 left--1 top-0 h-full w-1 bg-transparent cursor-col-resize"
17+
/>
18+
</NanoRightSidebar>
19+
<NanoRightActionBar v-if="!ctl.hideRightActionBar" ref="rightActionBar"/>
820
</div>
921
</template>
1022

@@ -15,7 +27,35 @@
1527
import NanoLeftActionBar from '@NanoUI/NanoLeftActionBar/index.vue';
1628
import NanoRightActionBar from '@NanoUI/NanoRightActionBar/index.vue';
1729
import { controllerStore } from '@store/controller';
30+
import { onMounted, ref } from 'vue';
31+
import { dragChangeWidth } from '../../utils/dragChangeWidth';
32+
1833
const ctl = controllerStore();
34+
35+
const body = ref<HTMLElement | null>(null);
36+
const leftActionBar = ref<InstanceType<typeof NanoLeftActionBar> | null>();
37+
const leftSidebar = ref<InstanceType<typeof NanoLeftSidebar> | null>();
38+
const rightSidebar = ref<InstanceType<typeof NanoRightSidebar> | null>();
39+
const rightActionBar = ref<InstanceType<typeof NanoRightActionBar> | null>();
40+
41+
const leftDraggableLine = ref<HTMLDivElement | null>();
42+
const rightDraggableLine = ref<HTMLDivElement | null>();
43+
44+
onMounted(() => {
45+
dragChangeWidth({
46+
parentEl: body.value!,
47+
targetEl: leftSidebar.value!.$el,
48+
dragEl: leftDraggableLine.value!,
49+
otherEls: [ rightSidebar.value!.$el, leftActionBar.value!.$el, rightActionBar.value!.$el ]
50+
});
51+
dragChangeWidth({
52+
parentEl: body.value!,
53+
targetEl: rightSidebar.value!.$el,
54+
dragEl: rightDraggableLine.value!,
55+
otherEls: [ leftSidebar.value!.$el, leftActionBar.value!.$el, rightActionBar.value!.$el ],
56+
reverseDirection: true
57+
});
58+
});
1959
</script>
2060

2161
<style scoped lang="scss">

package/components/NanoLeftSidebar/index.vue

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
<NanoSidebarDir ref="dir"/>
1111
<div class="grow w-full h-0"/>
1212
</div>
13-
<!--draggable line-->
14-
<div class="absolute z-2 right--1 top-0 h-full w-1 bg-transparent cursor-col-resize"/>
13+
<slot/>
1514
</div>
1615
</template>
1716

package/components/NanoRightSidebar/index.vue

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
ref="outline"
1212
/>
1313
</div>
14-
<!--draggable line-->
15-
<div class="absolute z-2 left--1 top-0 h-full w-1 bg-transparent cursor-col-resize"/>
14+
<slot/>
1615
</div>
1716
</template>
1817

package/utils/dragChangeWidth.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
type DragChangeWidthOptions = {
2+
parentEl: HTMLElement;
3+
targetEl: HTMLElement;
4+
dragEl: HTMLElement;
5+
otherEls: HTMLElement[];
6+
minWidth?: number;
7+
reservedWidth?: number;
8+
reverseDirection?: boolean;
9+
}
10+
11+
/**
12+
* 拖拽改变宽度
13+
* @param {Object} options
14+
* @param {HTMLElement} options.parentEl 父元素
15+
* @param {HTMLElement} options.targetEl 目标元素
16+
* @param {HTMLElement} options.dragEl 拖拽元素
17+
* @param {HTMLElement[]} options.otherEls 其他元素(用于控制目标元素最大宽度)
18+
* @param {number} options.minWidth 目标元素最小宽度
19+
* @param {number} [options.reservedWidth] 给其他元素预留的最小宽度
20+
* @param {boolean} [options.reverseDirection] 是否反向增加宽度
21+
*/
22+
export function dragChangeWidth(
23+
{
24+
parentEl,
25+
targetEl,
26+
dragEl,
27+
otherEls,
28+
minWidth = 160,
29+
reservedWidth = 400,
30+
reverseDirection = false
31+
}: DragChangeWidthOptions
32+
) {
33+
dragEl.addEventListener('mousedown', (e: MouseEvent) => {
34+
e.preventDefault();
35+
const startX = e.clientX;
36+
const bodyWidth = parentEl.clientWidth;
37+
const targetWidth = targetEl.clientWidth;
38+
// get otherEl width
39+
let otherTotalWidth = 0;
40+
otherEls.forEach(el => {
41+
otherTotalWidth += el.clientWidth;
42+
});
43+
44+
const onMouseMove = (e: MouseEvent) => {
45+
const diff = e.clientX - startX;
46+
const newTargetLine = targetWidth + (reverseDirection ? -diff : diff);
47+
// 控制最小宽度
48+
if (newTargetLine < minWidth) {
49+
return;
50+
}
51+
// 控制最大宽度
52+
if (newTargetLine > bodyWidth - otherTotalWidth - reservedWidth) {
53+
return;
54+
}
55+
const percentage = newTargetLine / bodyWidth * 100;
56+
targetEl.style.setProperty('width', `${ percentage }%`);
57+
};
58+
59+
const onMouseUp = () => {
60+
document.removeEventListener('mousemove', onMouseMove);
61+
document.removeEventListener('mouseup', onMouseUp);
62+
};
63+
64+
document.addEventListener('mousemove', onMouseMove);
65+
document.addEventListener('mouseup', onMouseUp);
66+
});
67+
};

0 commit comments

Comments
 (0)