Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
jxf111348
vue-vben-admin
提交
2e79c9f3
V
vue-vben-admin
项目概览
jxf111348
/
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,发现更多精彩内容 >>
提交
2e79c9f3
编写于
12月 21, 2020
作者:
V
vben
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: add ripple directive
上级
aafbb052
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
270 addition
and
1 deletion
+270
-1
CHANGELOG.zh_CN.md
CHANGELOG.zh_CN.md
+4
-0
src/directives/index.ts
src/directives/index.ts
+0
-0
src/directives/loading.ts
src/directives/loading.ts
+0
-0
src/directives/permission.ts
src/directives/permission.ts
+0
-0
src/directives/repeatClick.ts
src/directives/repeatClick.ts
+0
-0
src/directives/ripple/index.less
src/directives/ripple/index.less
+21
-0
src/directives/ripple/index.ts
src/directives/ripple/index.ts
+191
-0
src/locales/lang/en/routes/demo/feat.ts
src/locales/lang/en/routes/demo/feat.ts
+1
-0
src/locales/lang/zh_CN/routes/demo/feat.ts
src/locales/lang/zh_CN/routes/demo/feat.ts
+1
-0
src/main.ts
src/main.ts
+1
-1
src/router/menus/modules/demo/feat.ts
src/router/menus/modules/demo/feat.ts
+10
-0
src/router/routes/modules/demo/feat.ts
src/router/routes/modules/demo/feat.ts
+8
-0
src/views/demo/feat/ripple/index.vue
src/views/demo/feat/ripple/index.vue
+33
-0
未找到文件。
CHANGELOG.zh_CN.md
浏览文件 @
2e79c9f3
## Wip
### ✨ Features
-
新增
`v-ripple`
水波纹指令
### 🐛 Bug Fixes
-
修复混合模式下滚动条丢失问题
...
...
src/
setup/
directives/index.ts
→
src/directives/index.ts
浏览文件 @
2e79c9f3
文件已移动
src/
setup/
directives/loading.ts
→
src/directives/loading.ts
浏览文件 @
2e79c9f3
文件已移动
src/
setup/
directives/permission.ts
→
src/directives/permission.ts
浏览文件 @
2e79c9f3
文件已移动
src/
setup/
directives/repeatClick.ts
→
src/directives/repeatClick.ts
浏览文件 @
2e79c9f3
文件已移动
src/directives/ripple/index.less
0 → 100644
浏览文件 @
2e79c9f3
.ripple-container {
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
overflow: hidden;
pointer-events: none;
}
.ripple-effect {
position: relative;
z-index: 9999;
width: 1px;
height: 1px;
margin-top: 0;
margin-left: 0;
pointer-events: none;
border-radius: 50%;
transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
src/directives/ripple/index.ts
0 → 100644
浏览文件 @
2e79c9f3
import
{
Directive
}
from
'
vue
'
;
import
'
./index.less
'
;
export
interface
RippleOptions
{
event
:
string
;
transition
:
number
;
}
export
interface
RippleProto
{
background
?:
string
;
zIndex
?:
string
;
}
export
type
EventType
=
Event
&
MouseEvent
&
TouchEvent
;
const
options
:
RippleOptions
=
{
event
:
'
mousedown
'
,
transition
:
400
,
};
const
RippleDirective
:
Directive
&
RippleProto
=
{
beforeMount
:
(
el
:
HTMLElement
,
binding
)
=>
{
if
(
binding
.
value
===
false
)
return
;
const
bg
=
el
.
getAttribute
(
'
ripple-background
'
);
setProps
(
Object
.
keys
(
binding
.
modifiers
),
options
);
const
background
=
bg
||
RippleDirective
.
background
;
const
zIndex
=
RippleDirective
.
zIndex
;
el
.
addEventListener
(
options
.
event
,
(
event
:
EventType
)
=>
{
rippler
({
event
,
el
,
background
,
zIndex
,
});
});
},
updated
(
el
,
binding
)
{
if
(
!
binding
.
value
)
{
el
?.
clearRipple
?.();
return
;
}
const
bg
=
el
.
getAttribute
(
'
ripple-background
'
);
el
?.
setBackground
?.(
bg
);
},
};
function
rippler
({
event
,
el
,
zIndex
,
background
,
}:
{
event
:
EventType
;
el
:
HTMLElement
}
&
RippleProto
)
{
const
targetBorder
=
parseInt
(
getComputedStyle
(
el
).
borderWidth
.
replace
(
'
px
'
,
''
));
const
clientX
=
event
.
clientX
||
event
.
touches
[
0
].
clientX
;
const
clientY
=
event
.
clientY
||
event
.
touches
[
0
].
clientY
;
const
rect
=
el
.
getBoundingClientRect
();
const
{
left
,
top
}
=
rect
;
const
{
offsetWidth
:
width
,
offsetHeight
:
height
}
=
el
;
const
{
transition
}
=
options
;
const
dx
=
clientX
-
left
;
const
dy
=
clientY
-
top
;
const
maxX
=
Math
.
max
(
dx
,
width
-
dx
);
const
maxY
=
Math
.
max
(
dy
,
height
-
dy
);
const
style
=
window
.
getComputedStyle
(
el
);
const
radius
=
Math
.
sqrt
(
maxX
*
maxX
+
maxY
*
maxY
);
const
border
=
targetBorder
>
0
?
targetBorder
:
0
;
const
ripple
=
document
.
createElement
(
'
div
'
);
const
rippleContainer
=
document
.
createElement
(
'
div
'
);
// Styles for ripple
Object
.
assign
(
ripple
.
style
??
{},
{
className
:
'
ripple
'
,
marginTop
:
'
0px
'
,
marginLeft
:
'
0px
'
,
width
:
'
1px
'
,
height
:
'
1px
'
,
transition
:
`all
${
transition
}
ms cubic-bezier(0.4, 0, 0.2, 1)`
,
borderRadius
:
'
50%
'
,
pointerEvents
:
'
none
'
,
position
:
'
relative
'
,
zIndex
:
zIndex
??
'
9999
'
,
backgroundColor
:
background
??
'
rgba(0, 0, 0, 0.12)
'
,
});
// Styles for rippleContainer
Object
.
assign
(
rippleContainer
.
style
??
{},
{
className
:
'
ripple-container
'
,
position
:
'
absolute
'
,
left
:
`
${
0
-
border
}
px`
,
top
:
`
${
0
-
border
}
px`
,
height
:
'
0
'
,
width
:
'
0
'
,
pointerEvents
:
'
none
'
,
overflow
:
'
hidden
'
,
});
const
storedTargetPosition
=
el
.
style
.
position
.
length
>
0
?
el
.
style
.
position
:
getComputedStyle
(
el
).
position
;
if
(
storedTargetPosition
!==
'
relative
'
)
{
el
.
style
.
position
=
'
relative
'
;
}
rippleContainer
.
appendChild
(
ripple
);
el
.
appendChild
(
rippleContainer
);
Object
.
assign
(
ripple
.
style
,
{
marginTop
:
`
${
dy
}
px`
,
marginLeft
:
`
${
dx
}
px`
,
});
const
{
borderTopLeftRadius
,
borderTopRightRadius
,
borderBottomLeftRadius
,
borderBottomRightRadius
,
}
=
style
;
Object
.
assign
(
rippleContainer
.
style
,
{
width
:
`
${
width
}
px`
,
height
:
`
${
height
}
px`
,
direction
:
'
ltr
'
,
borderTopLeftRadius
,
borderTopRightRadius
,
borderBottomLeftRadius
,
borderBottomRightRadius
,
});
setTimeout
(()
=>
{
const
wh
=
`
${
radius
*
2
}
px`
;
Object
.
assign
(
ripple
.
style
??
{},
{
width
:
wh
,
height
:
wh
,
marginLeft
:
`
${
dx
-
radius
}
px`
,
marginTop
:
`
${
dy
-
radius
}
px`
,
});
},
0
);
function
clearRipple
()
{
setTimeout
(()
=>
{
ripple
.
style
.
backgroundColor
=
'
rgba(0, 0, 0, 0)
'
;
},
250
);
setTimeout
(()
=>
{
rippleContainer
?.
parentNode
?.
removeChild
(
rippleContainer
);
},
850
);
el
.
removeEventListener
(
'
mouseup
'
,
clearRipple
,
false
);
el
.
removeEventListener
(
'
mouseleave
'
,
clearRipple
,
false
);
el
.
removeEventListener
(
'
dragstart
'
,
clearRipple
,
false
);
setTimeout
(()
=>
{
let
clearPosition
=
true
;
for
(
let
i
=
0
;
i
<
el
.
childNodes
.
length
;
i
++
)
{
if
((
el
.
childNodes
[
i
]
as
any
).
className
===
'
ripple-container
'
)
{
clearPosition
=
false
;
}
}
if
(
clearPosition
)
{
el
.
style
.
position
=
storedTargetPosition
!==
'
static
'
?
storedTargetPosition
:
''
;
}
},
options
.
transition
+
260
);
}
if
(
event
.
type
===
'
mousedown
'
)
{
el
.
addEventListener
(
'
mouseup
'
,
clearRipple
,
false
);
el
.
addEventListener
(
'
mouseleave
'
,
clearRipple
,
false
);
el
.
addEventListener
(
'
dragstart
'
,
clearRipple
,
false
);
}
else
{
clearRipple
();
}
(
el
as
any
).
setBackground
=
(
bgColor
:
string
)
=>
{
if
(
!
bgColor
)
{
return
;
}
ripple
.
style
.
backgroundColor
=
bgColor
;
};
}
function
setProps
(
modifiers
:
{
[
key
:
string
]:
any
},
props
:
Record
<
string
,
any
>
)
{
modifiers
.
forEach
((
item
:
any
)
=>
{
if
(
isNaN
(
Number
(
item
)))
props
.
event
=
item
;
else
props
.
transition
=
item
;
});
}
export
default
RippleDirective
;
src/locales/lang/en/routes/demo/feat.ts
浏览文件 @
2e79c9f3
...
...
@@ -9,6 +9,7 @@ export default {
copy
:
'
Clipboard
'
,
msg
:
'
Message prompt
'
,
watermark
:
'
Watermark
'
,
ripple
:
'
Ripple
'
,
fullScreen
:
'
Full Screen
'
,
errorLog
:
'
Error Log
'
,
tab
:
'
Tab with parameters
'
,
...
...
src/locales/lang/zh_CN/routes/demo/feat.ts
浏览文件 @
2e79c9f3
...
...
@@ -9,6 +9,7 @@ export default {
copy
:
'
剪切板
'
,
msg
:
'
消息提示
'
,
watermark
:
'
水印
'
,
ripple
:
'
水波纹
'
,
fullScreen
:
'
全屏
'
,
errorLog
:
'
错误日志
'
,
tab
:
'
Tab带参
'
,
...
...
src/main.ts
浏览文件 @
2e79c9f3
...
...
@@ -5,7 +5,7 @@ import router, { setupRouter } from '/@/router';
import
{
setupStore
}
from
'
/@/store
'
;
import
{
setupAntd
}
from
'
/@/setup/ant-design-vue
'
;
import
{
setupErrorHandle
}
from
'
/@/setup/error-handle
'
;
import
{
setupGlobDirectives
}
from
'
/@/
setup/
directives
'
;
import
{
setupGlobDirectives
}
from
'
/@/directives
'
;
import
{
setupI18n
}
from
'
/@/setup/i18n
'
;
import
{
setupProdMockServer
}
from
'
../mock/_createProductionServer
'
;
import
{
setApp
}
from
'
/@/setup/App
'
;
...
...
src/router/menus/modules/demo/feat.ts
浏览文件 @
2e79c9f3
...
...
@@ -6,6 +6,9 @@ const menu: MenuModule = {
menu
:
{
name
:
t
(
'
routes.demo.feat.feat
'
),
path
:
'
/feat
'
,
tag
:
{
dot
:
true
,
},
children
:
[
{
...
...
@@ -44,6 +47,13 @@ const menu: MenuModule = {
path
:
'
watermark
'
,
name
:
t
(
'
routes.demo.feat.watermark
'
),
},
{
path
:
'
ripple
'
,
name
:
t
(
'
routes.demo.feat.ripple
'
),
tag
:
{
content
:
'
new
'
,
},
},
{
path
:
'
full-screen
'
,
name
:
t
(
'
routes.demo.feat.fullScreen
'
),
...
...
src/router/routes/modules/demo/feat.ts
浏览文件 @
2e79c9f3
...
...
@@ -86,6 +86,14 @@ const feat: AppRouteModule = {
title
:
t
(
'
routes.demo.feat.watermark
'
),
},
},
{
path
:
'
ripple
'
,
name
:
'
RippleDemo
'
,
component
:
()
=>
import
(
'
/@/views/demo/feat/ripple/index.vue
'
),
meta
:
{
title
:
t
(
'
routes.demo.feat.ripple
'
),
},
},
{
path
:
'
full-screen
'
,
name
:
'
FullScreenDemo
'
,
...
...
src/views/demo/feat/ripple/index.vue
0 → 100644
浏览文件 @
2e79c9f3
<
template
>
<div
class=
"p-4"
>
<div
class=
"demo-box"
v-ripple
>
content
</div>
</div>
</
template
>
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'
vue
'
;
import
{
Alert
}
from
'
ant-design-vue
'
;
import
RippleDirective
from
'
/@/directives/ripple
'
;
export
default
defineComponent
({
components
:
{
Alert
},
directives
:
{
Ripple
:
RippleDirective
,
},
setup
()
{
return
{};
},
});
</
script
>
<
style
lang=
"less"
scoped
>
.demo-box {
display: flex;
width: 300px;
height: 300px;
font-size: 24px;
color: #fff;
background: #408ede;
border-radius: 10px;
justify-content: center;
align-items: center;
}
</
style
>
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录