Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
一臭打代码的 aka 潘先生です
vue-vben-admin
提交
5af45275
V
vue-vben-admin
项目概览
一臭打代码的 aka 潘先生です
/
vue-vben-admin
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vue-vben-admin
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
5af45275
编写于
9月 18, 2021
作者:
无
无木
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: hmr error fixed
修复部分组件可能会造成热更新异常的问题
上级
9c5f11a5
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
128 addition
and
153 deletion
+128
-153
CHANGELOG.zh_CN.md
CHANGELOG.zh_CN.md
+3
-1
src/components/Dropdown/src/Dropdown.vue
src/components/Dropdown/src/Dropdown.vue
+53
-66
src/components/Icon/src/IconPicker.vue
src/components/Icon/src/IconPicker.vue
+72
-86
未找到文件。
CHANGELOG.zh_CN.md
浏览文件 @
5af45275
...
...
@@ -16,7 +16,9 @@
-
修复点击关闭按钮、最大化按钮旁边的空白区域也会导致
`Modal`
关闭的问题
-
**BasicTree**
修复节点插槽不起作用的问题
-
**CodeEditor**
修复可能会造成的
`Build`
失败的问题
-
**其它**
修复多标签在某些情况下关闭页签不会跳转路由的问题
-
**其它**
-
修复多标签在某些情况下关闭页签不会跳转路由的问题
-
修复部分组件可能会造成热更新异常的问题
## 2.7.2(2021-09-14)
...
...
src/components/Dropdown/src/Dropdown.vue
浏览文件 @
5af45275
<
template
>
<
D
ropdown
:trigger=
"trigger"
v-bind=
"$attrs"
>
<
a-d
ropdown
:trigger=
"trigger"
v-bind=
"$attrs"
>
<span>
<slot></slot>
</span>
<template
#overlay
>
<
M
enu
:selectedKeys=
"selectedKeys"
>
<
a-m
enu
:selectedKeys=
"selectedKeys"
>
<template
v-for=
"item in dropMenuList"
:key=
"`$
{item.event}`">
<
MenuI
tem
<
a-menu-i
tem
v-bind=
"getAttr(item.event)"
@
click=
"handleClickMenu(item)"
:disabled=
"item.disabled"
>
<
P
opconfirm
<
a-p
opconfirm
v-if=
"popconfirm && item.popConfirm"
v-bind=
"getPopConfirmAttrs(item.popConfirm)"
>
...
...
@@ -22,86 +22,73 @@
<Icon
:icon=
"item.icon"
v-if=
"item.icon"
/>
<span
class=
"ml-1"
>
{{ item.text }}
</span>
</div>
</
P
opconfirm>
</
a-p
opconfirm>
<
template
v-else
>
<Icon
:icon=
"item.icon"
v-if=
"item.icon"
/>
<span
class=
"ml-1"
>
{{
item
.
text
}}
</span>
</
template
>
</
MenuI
tem>
<
MenuD
ivider
v-if=
"item.divider"
:key=
"`d-${item.event}`"
/>
</
a-menu-i
tem>
<
a-menu-d
ivider
v-if=
"item.divider"
:key=
"`d-${item.event}`"
/>
</template>
</
M
enu>
</
a-m
enu>
</template>
</
D
ropdown>
</
a-d
ropdown>
</template>
<
script
lang=
"ts"
>
<
script
lang=
"ts"
setup
>
import
{
computed
,
PropType
}
from
'
vue
'
;
import
type
{
DropMenu
}
from
'
./typing
'
;
import
{
defineComponent
}
from
'
vue
'
;
import
{
Dropdown
,
Menu
,
Popconfirm
}
from
'
ant-design-vue
'
;
import
{
Icon
}
from
'
/@/components/Icon
'
;
import
{
omit
}
from
'
lodash-es
'
;
import
{
isFunction
}
from
'
/@/utils/is
'
;
export
default
defineComponent
({
name
:
'
BasicDropdown
'
,
components
:
{
Dropdown
,
Menu
,
MenuItem
:
Menu
.
Item
,
MenuDivider
:
Menu
.
Divider
,
Icon
,
Popconfirm
,
},
props
:
{
popconfirm
:
Boolean
,
/**
* the trigger mode which executes the drop-down action
* @default ['hover']
* @type string[]
*/
trigger
:
{
type
:
[
Array
]
as
PropType
<
(
'
contextmenu
'
|
'
click
'
|
'
hover
'
)[]
>
,
default
:
()
=>
{
return
[
'
contextmenu
'
];
},
},
dropMenuList
:
{
type
:
Array
as
PropType
<
(
DropMenu
&
Recordable
)[]
>
,
default
:
()
=>
[],
},
selectedKeys
:
{
type
:
Array
as
PropType
<
string
[]
>
,
default
:
()
=>
[],
const
ADropdown
=
Dropdown
;
const
AMenu
=
Menu
;
const
AMenuItem
=
Menu
.
Item
;
const
AMenuDivider
=
Menu
.
Divider
;
const
APopconfirm
=
Popconfirm
;
const
props
=
defineProps
({
popconfirm
:
Boolean
,
/**
* the trigger mode which executes the drop-down action
* @default ['hover']
* @type string[]
*/
trigger
:
{
type
:
[
Array
]
as
PropType
<
(
'
contextmenu
'
|
'
click
'
|
'
hover
'
)[]
>
,
default
:
()
=>
{
return
[
'
contextmenu
'
];
},
},
emits
:
[
'
menuEvent
'
],
setup
(
props
,
{
emit
})
{
function
handleClickMenu
(
item
:
DropMenu
)
{
const
{
event
}
=
item
;
const
menu
=
props
.
dropMenuList
.
find
((
item
)
=>
`
${
item
.
event
}
`
===
`
${
event
}
`
);
emit
(
'
menuEvent
'
,
menu
);
item
.
onClick
?.();
}
dropMenuList
:
{
type
:
Array
as
PropType
<
(
DropMenu
&
Recordable
)[]
>
,
default
:
()
=>
[],
},
selectedKeys
:
{
type
:
Array
as
PropType
<
string
[]
>
,
default
:
()
=>
[],
},
});
const
getPopConfirmAttrs
=
computed
(()
=>
{
return
(
attrs
)
=>
{
const
originAttrs
=
omit
(
attrs
,
[
'
confirm
'
,
'
cancel
'
,
'
icon
'
]);
if
(
!
attrs
.
onConfirm
&&
attrs
.
confirm
&&
isFunction
(
attrs
.
confirm
))
originAttrs
[
'
onConfirm
'
]
=
attrs
.
confirm
;
if
(
!
attrs
.
onCancel
&&
attrs
.
cancel
&&
isFunction
(
attrs
.
cancel
))
originAttrs
[
'
onCancel
'
]
=
attrs
.
cancel
;
return
originAttrs
;
};
});
const
emit
=
defineEmits
([
'
menuEvent
'
]);
return
{
handleClickMenu
,
getPopConfirmAttrs
,
getAttr
:
(
key
:
string
|
number
)
=>
({
key
}),
};
},
function
handleClickMenu
(
item
:
DropMenu
)
{
const
{
event
}
=
item
;
const
menu
=
props
.
dropMenuList
.
find
((
item
)
=>
`
${
item
.
event
}
`
===
`
${
event
}
`
);
emit
(
'
menuEvent
'
,
menu
);
item
.
onClick
?.();
}
const
getPopConfirmAttrs
=
computed
(()
=>
{
return
(
attrs
)
=>
{
const
originAttrs
=
omit
(
attrs
,
[
'
confirm
'
,
'
cancel
'
,
'
icon
'
]);
if
(
!
attrs
.
onConfirm
&&
attrs
.
confirm
&&
isFunction
(
attrs
.
confirm
))
originAttrs
[
'
onConfirm
'
]
=
attrs
.
confirm
;
if
(
!
attrs
.
onCancel
&&
attrs
.
cancel
&&
isFunction
(
attrs
.
cancel
))
originAttrs
[
'
onCancel
'
]
=
attrs
.
cancel
;
return
originAttrs
;
};
});
</
script
>
src/components/Icon/src/IconPicker.vue
浏览文件 @
5af45275
...
...
@@ -7,7 +7,7 @@
v-model:value="currentSelect"
>
<template
#addonAfter
>
<
P
opover
<
a-p
opover
placement=
"bottomLeft"
trigger=
"click"
v-model=
"visible"
...
...
@@ -17,7 +17,7 @@
<div
class=
"flex justify-between"
>
<a-input
:placeholder=
"t('component.icon.search')"
@
change=
"
h
andleSearchChange"
@
change=
"
debounceH
andleSearchChange"
allowClear
/>
</div>
...
...
@@ -53,7 +53,7 @@
</ul>
</ScrollContainer>
<div
class=
"flex py-2 items-center justify-center"
v-if=
"getTotal >= pageSize"
>
<
P
agination
<
a-p
agination
showLessItems
size=
"small"
:pageSize=
"pageSize"
...
...
@@ -63,7 +63,7 @@
</div>
</div>
<template
v-else
><div
class=
"p-5"
><
E
mpty
/></div>
><div
class=
"p-5"
><
a-e
mpty
/></div>
</
template
>
</template>
...
...
@@ -71,16 +71,14 @@
<SvgIcon
:name=
"currentSelect"
/>
</span>
<Icon
:icon=
"currentSelect || 'ion:apps-outline'"
class=
"cursor-pointer px-2 py-1"
v-else
/>
</
P
opover>
</
a-p
opover>
</template>
</a-input>
</template>
<
script
lang=
"ts"
>
import
{
defineComponent
,
ref
,
watchEffect
,
watch
,
unref
}
from
'
vue
'
;
<
script
lang=
"ts"
setup
>
import
{
ref
,
watchEffect
,
watch
,
unref
}
from
'
vue
'
;
import
{
useDesign
}
from
'
/@/hooks/web/useDesign
'
;
import
{
ScrollContainer
}
from
'
/@/components/Container
'
;
import
{
Input
,
Popover
,
Pagination
,
Empty
}
from
'
ant-design-vue
'
;
import
Icon
from
'
./Icon.vue
'
;
import
SvgIcon
from
'
./SvgIcon.vue
'
;
...
...
@@ -94,6 +92,12 @@
import
{
useMessage
}
from
'
/@/hooks/web/useMessage
'
;
import
svgIcons
from
'
virtual:svg-icons-names
'
;
// 没有使用别名引入,是因为WebStorm当前版本还不能正确识别,会报unused警告
const
AInput
=
Input
;
const
APopover
=
Popover
;
const
APagination
=
Pagination
;
const
AEmpty
=
Empty
;
function
getIcons
()
{
const
data
=
iconsData
as
any
;
const
prefix
:
string
=
data
?.
prefix
??
''
;
...
...
@@ -110,88 +114,70 @@
return
svgIcons
.
map
((
icon
)
=>
icon
.
replace
(
'
icon-
'
,
''
));
}
export
default
defineComponent
({
name
:
'
IconPicker
'
,
components
:
{
[
Input
.
name
]:
Input
,
Icon
,
Popover
,
ScrollContainer
,
Pagination
,
Empty
,
SvgIcon
},
inheritAttrs
:
false
,
props
:
{
value
:
propTypes
.
string
,
width
:
propTypes
.
string
.
def
(
'
100%
'
),
pageSize
:
propTypes
.
number
.
def
(
140
),
copy
:
propTypes
.
bool
.
def
(
false
),
mode
:
propTypes
.
oneOf
<
(
'
svg
'
|
'
iconify
'
)[]
>
([
'
svg
'
,
'
iconify
'
]).
def
(
'
iconify
'
),
const
props
=
defineProps
({
value
:
propTypes
.
string
,
width
:
propTypes
.
string
.
def
(
'
100%
'
),
pageSize
:
propTypes
.
number
.
def
(
140
),
copy
:
propTypes
.
bool
.
def
(
false
),
mode
:
propTypes
.
oneOf
<
(
'
svg
'
|
'
iconify
'
)[]
>
([
'
svg
'
,
'
iconify
'
]).
def
(
'
iconify
'
),
});
const
emit
=
defineEmits
([
'
change
'
,
'
update:value
'
]);
const
isSvgMode
=
props
.
mode
===
'
svg
'
;
const
icons
=
isSvgMode
?
getSvgIcons
()
:
getIcons
();
const
currentSelect
=
ref
(
''
);
const
visible
=
ref
(
false
);
const
currentList
=
ref
(
icons
);
const
{
t
}
=
useI18n
();
const
{
prefixCls
}
=
useDesign
(
'
icon-picker
'
);
const
debounceHandleSearchChange
=
useDebounceFn
(
handleSearchChange
,
100
);
const
{
clipboardRef
,
isSuccessRef
}
=
useCopyToClipboard
(
props
.
value
);
const
{
createMessage
}
=
useMessage
();
const
{
getPaginationList
,
getTotal
,
setCurrentPage
}
=
usePagination
(
currentList
,
props
.
pageSize
,
);
watchEffect
(()
=>
{
currentSelect
.
value
=
props
.
value
;
});
watch
(
()
=>
currentSelect
.
value
,
(
v
)
=>
{
emit
(
'
update:value
'
,
v
);
return
emit
(
'
change
'
,
v
);
},
emits
:
[
'
change
'
,
'
update:value
'
],
setup
(
props
,
{
emit
})
{
const
isSvgMode
=
props
.
mode
===
'
svg
'
;
const
icons
=
isSvgMode
?
getSvgIcons
()
:
getIcons
();
const
currentSelect
=
ref
(
''
);
const
visible
=
ref
(
false
);
const
currentList
=
ref
(
icons
);
const
{
t
}
=
useI18n
();
const
{
prefixCls
}
=
useDesign
(
'
icon-picker
'
);
const
debounceHandleSearchChange
=
useDebounceFn
(
handleSearchChange
,
100
);
const
{
clipboardRef
,
isSuccessRef
}
=
useCopyToClipboard
(
props
.
value
);
const
{
createMessage
}
=
useMessage
();
const
{
getPaginationList
,
getTotal
,
setCurrentPage
}
=
usePagination
(
currentList
,
props
.
pageSize
,
);
watchEffect
(()
=>
{
currentSelect
.
value
=
props
.
value
;
});
watch
(
()
=>
currentSelect
.
value
,
(
v
)
=>
{
emit
(
'
update:value
'
,
v
);
return
emit
(
'
change
'
,
v
);
},
);
function
handlePageChange
(
page
:
number
)
{
setCurrentPage
(
page
);
}
);
function
handleClick
(
icon
:
string
)
{
currentSelect
.
value
=
icon
;
if
(
props
.
copy
)
{
clipboardRef
.
value
=
icon
;
if
(
unref
(
isSuccessRef
))
{
createMessage
.
success
(
t
(
'
component.icon.copy
'
));
}
}
}
function
handlePageChange
(
page
:
number
)
{
setCurrentPage
(
page
);
}
function
handleSearchChange
(
e
:
ChangeEvent
)
{
const
value
=
e
.
target
.
value
;
if
(
!
value
)
{
setCurrentPage
(
1
);
currentList
.
value
=
icons
;
return
;
}
currentList
.
value
=
icons
.
filter
((
item
)
=>
item
.
includes
(
value
));
function
handleClick
(
icon
:
string
)
{
currentSelect
.
value
=
icon
;
if
(
props
.
copy
)
{
clipboardRef
.
value
=
icon
;
if
(
unref
(
isSuccessRef
))
{
createMessage
.
success
(
t
(
'
component.icon.copy
'
));
}
}
}
return
{
t
,
prefixCls
,
visible
,
isSvgMode
,
getTotal
,
getPaginationList
,
handlePageChange
,
handleClick
,
currentSelect
,
handleSearchChange
:
debounceHandleSearchChange
,
};
},
});
function
handleSearchChange
(
e
:
ChangeEvent
)
{
const
value
=
e
.
target
.
value
;
if
(
!
value
)
{
setCurrentPage
(
1
);
currentList
.
value
=
icons
;
return
;
}
currentList
.
value
=
icons
.
filter
((
item
)
=>
item
.
includes
(
value
));
}
</
script
>
<
style
lang=
"less"
>
@prefix-cls: ~'@{namespace}-icon-picker';
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录