Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
ebacbbb9
authored
Apr 22, 2023
by
dhb52
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
perf: mp/menu使用vuedraggable替换拖动的原生实现
parent
08eb72e5
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
55 additions
and
39 deletions
+55
-39
src/views/mp/menu/components/MenuPreviewer.vue
+55
-39
No files found.
src/views/mp/menu/components/MenuPreviewer.vue
View file @
ebacbbb9
<
template
>
<
template
>
<div
class=
"menu_bottom"
v-for=
"(parent, x) of menuList"
:key=
"x"
>
<draggable
v-model=
"menuList"
item-key=
"id"
ghost-class=
"draggable-ghost"
:animation=
"400"
@
end=
"onDragEnd"
>
<template
#
item=
"
{ element: parent, index: x }">
<div
class=
"menu_bottom"
>
<!-- 一级菜单 -->
<!-- 一级菜单 -->
<div
<div
@
click=
"menuClicked(parent, x)"
@
click=
"menuClicked(parent, x)"
class=
"menu_item"
class=
"menu_item"
draggable=
"true"
@
dragstart=
"onDragStart(DragType.Parent, x)"
@
dragenter
.
prevent=
"onDragEnter(DragType.Parent, x)"
:class=
"
{ active: props.activeIndex === `${x}` }"
:class=
"
{ active: props.activeIndex === `${x}` }"
>
>
<Icon
icon=
"ep:fold"
color=
"black"
/>
{{
parent
.
name
}}
<Icon
icon=
"ep:fold"
color=
"black"
/>
{{
parent
.
name
}}
</div>
</div>
<!-- 以下为二级菜单-->
<!-- 以下为二级菜单-->
<div
class=
"submenu"
v-if=
"parentIndex === x && parent.children"
>
<div
class=
"submenu"
v-if=
"props.parentIndex === x && parent.children"
>
<div
class=
"subtitle menu_bottom"
v-for=
"(child, y) in parent.children"
:key=
"y"
>
<draggable
v-model=
"parent.children"
item-key=
"id"
ghost-class=
"draggable-ghost"
:animation=
"400"
>
<template
#
item=
"
{ element: child, index: y }">
<div
class=
"subtitle menu_bottom"
>
<div
<div
class=
"menu_subItem"
class=
"menu_subItem"
draggable=
"true"
@
dragstart=
"onDragStart(DragType.Child, y)"
@
dragenter
.
prevent=
"onDragEnter(DragType.Child, x, y)"
v-if=
"parent.children"
v-if=
"parent.children"
:class=
"
{ active: props.activeIndex === `${x}-${y}` }"
:class=
"
{ active: props.activeIndex === `${x}-${y}` }"
@click="subMenuClicked(child, x, y)"
@click="subMenuClicked(child, x, y)"
...
@@ -26,6 +35,8 @@
...
@@ -26,6 +35,8 @@
{{
child
.
name
}}
{{
child
.
name
}}
</div>
</div>
</div>
</div>
</
template
>
</draggable>
<!-- 二级菜单加号, 当长度 小于 5 才显示二级菜单的加号 -->
<!-- 二级菜单加号, 当长度 小于 5 才显示二级菜单的加号 -->
<div
<div
class=
"menu_bottom menu_addicon"
class=
"menu_bottom menu_addicon"
...
@@ -36,6 +47,9 @@
...
@@ -36,6 +47,9 @@
</div>
</div>
</div>
</div>
</div>
</div>
</template>
</draggable>
<!-- 一级菜单加号 -->
<!-- 一级菜单加号 -->
<div
class=
"menu_bottom menu_addicon"
v-if=
"menuList.length < 3"
@
click=
"addMenu"
>
<div
class=
"menu_bottom menu_addicon"
v-if=
"menuList.length < 3"
@
click=
"addMenu"
>
<Icon
icon=
"ep:plus"
class=
"plus"
/>
<Icon
icon=
"ep:plus"
class=
"plus"
/>
...
@@ -44,6 +58,7 @@
...
@@ -44,6 +58,7 @@
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
{
Menu
}
from
'./types'
import
{
Menu
}
from
'./types'
import
draggable
from
'vuedraggable'
const
props
=
defineProps
<
{
const
props
=
defineProps
<
{
modelValue
:
Menu
[]
modelValue
:
Menu
[]
...
@@ -97,46 +112,41 @@ const addSubMenu = (i: number, parent: any) => {
...
@@ -97,46 +112,41 @@ const addSubMenu = (i: number, parent: any) => {
const
menuClicked
=
(
parent
:
Menu
,
x
:
number
)
=>
{
const
menuClicked
=
(
parent
:
Menu
,
x
:
number
)
=>
{
emit
(
'menu-clicked'
,
parent
,
x
)
emit
(
'menu-clicked'
,
parent
,
x
)
}
}
const
subMenuClicked
=
(
child
:
Menu
,
x
:
number
,
y
:
number
)
=>
{
const
subMenuClicked
=
(
child
:
Menu
,
x
:
number
,
y
:
number
)
=>
{
emit
(
'submenu-clicked'
,
child
,
x
,
y
)
emit
(
'submenu-clicked'
,
child
,
x
,
y
)
}
}
// ======================== 菜单排序 ========================
const
dragIndex
=
ref
<
number
>
(
0
)
enum
DragType
{
Parent
=
'parent'
,
Child
=
'child'
}
const
dragType
=
ref
<
DragType
>
()
/**
/**
*
菜单开始拖动回调,记录被拖动菜单的信息(类型,下标)
*
处理一级菜单展开后被拖动
*
*
* @param
type DragType, 拖动类型,父节点、子节点
* @param
oldIndex: 一级菜单拖动前的位置
* @param
index number, 被拖动的菜单下标
* @param
newIndex: 一级菜单拖动后的位置
*/
*/
const
onDragStart
=
(
type
:
DragType
,
index
:
number
)
=>
{
const
onDragEnd
=
({
oldIndex
,
newIndex
})
=>
{
dragIndex
.
value
=
index
// 二级菜单没有展开,直接返回
dragType
.
value
=
type
if
(
props
.
activeIndex
===
'__MENU_NOT_SELECTED__'
)
{
}
return
}
/**
let
newParent
=
props
.
parentIndex
* 拖动其他菜单位置回调, 判断【被拖动】及【被替换位置】的两个菜单是否同个类型,同类型才会进行插入
if
(
props
.
parentIndex
===
oldIndex
)
{
*
newParent
=
newIndex
* @param type: DragType, 拖动类型,父节点、子节点
}
else
if
(
props
.
parentIndex
===
newIndex
)
{
* @param x number, 准备替换父节点位置的下标
newParent
=
oldIndex
* @param y number, 准备替换子节点位置的下标, 父节点拖动时可选
*/
const
onDragEnter
=
(
type
:
DragType
,
x
:
number
,
y
=
-
1
)
=>
{
if
(
dragIndex
.
value
!==
x
&&
dragType
.
value
===
type
)
{
if
(
type
===
DragType
.
Parent
)
{
const
source
=
menuList
.
value
.
splice
(
dragIndex
.
value
,
1
)
menuList
.
value
.
splice
(
x
,
0
,
...
source
)
}
else
{
}
else
{
const
source
=
menuList
.
value
[
x
].
children
?.
splice
(
dragIndex
.
value
,
1
)
// 如果展开的二级菜单下标`props.parentIndex`不是被移动的菜单的前后下标。
menuList
.
value
[
x
].
children
?.
splice
(
y
,
0
,
...(
source
as
any
))
// 那么使用一个辅助素组来模拟菜单移动,然后找到展开的二级菜单的新下标`newParent`
}
let
positions
=
new
Array
<
boolean
>
(
menuList
.
value
.
length
).
fill
(
false
)
positions
[
props
.
parentIndex
]
=
true
positions
.
splice
(
oldIndex
,
1
)
positions
.
splice
(
newIndex
,
0
,
true
)
newParent
=
positions
.
indexOf
(
true
)
}
}
// 找到菜单元素,触发一级菜单点击
const
parent
=
menuList
.
value
[
newParent
]
emit
(
'menu-clicked'
,
parent
,
newParent
)
}
}
</
script
>
</
script
>
...
@@ -199,4 +209,10 @@ const onDragEnter = (type: DragType, x: number, y = -1) => {
...
@@ -199,4 +209,10 @@ const onDragEnter = (type: DragType, x: number, y = -1) => {
box-sizing
:
border-box
;
box-sizing
:
border-box
;
}
}
}
}
.draggable-ghost
{
opacity
:
0.5
;
background
:
#f7fafc
;
border
:
1px
solid
#4299e1
;
}
</
style
>
</
style
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment