Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Simoje丶
vue-vben-admin
提交
bd2039ac
V
vue-vben-admin
项目概览
Simoje丶
/
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 搜索 >>
提交
bd2039ac
编写于
6月 11, 2021
作者:
V
Vben
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
refactor: remove useExpose
上级
3b2c40be
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
610 addition
and
613 deletion
+610
-613
CHANGELOG.zh_CN.md
CHANGELOG.zh_CN.md
+4
-0
src/components/Table/src/BasicTable.vue
src/components/Table/src/BasicTable.vue
+2
-3
src/components/Tree/src/Tree.vue
src/components/Tree/src/Tree.vue
+2
-3
src/components/Verify/index.ts
src/components/Verify/index.ts
+6
-5
src/components/Verify/src/DragVerify.less
src/components/Verify/src/DragVerify.less
+0
-87
src/components/Verify/src/DragVerify.tsx
src/components/Verify/src/DragVerify.tsx
+0
-283
src/components/Verify/src/DragVerify.vue
src/components/Verify/src/DragVerify.vue
+375
-0
src/components/Verify/src/ImgRotate.less
src/components/Verify/src/ImgRotate.less
+0
-51
src/components/Verify/src/ImgRotate.tsx
src/components/Verify/src/ImgRotate.tsx
+0
-172
src/components/Verify/src/ImgRotate.vue
src/components/Verify/src/ImgRotate.vue
+221
-0
src/components/Verify/src/typing.ts
src/components/Verify/src/typing.ts
+0
-0
src/hooks/core/useExpose.ts
src/hooks/core/useExpose.ts
+0
-9
未找到文件。
CHANGELOG.zh_CN.md
浏览文件 @
bd2039ac
## Wip
### ✨ Refactor
-
移除
`useExpose`
,使用组件自身提供的
`expose`
代替
### ✨ Features
-
**CropperImage**
`Cropper`
头像裁剪新增圆形裁剪功能
...
...
src/components/Table/src/BasicTable.vue
浏览文件 @
bd2039ac
...
...
@@ -59,7 +59,6 @@
import
{
createTableContext
}
from
'
./hooks/useTableContext
'
;
import
{
useTableFooter
}
from
'
./hooks/useTableFooter
'
;
import
{
useTableForm
}
from
'
./hooks/useTableForm
'
;
import
{
useExpose
}
from
'
/@/hooks/core/useExpose
'
;
import
{
useDesign
}
from
'
/@/hooks/web/useDesign
'
;
import
{
omit
}
from
'
lodash-es
'
;
...
...
@@ -91,7 +90,7 @@
'
change
'
,
'
columns-change
'
,
],
setup
(
props
,
{
attrs
,
emit
,
slots
})
{
setup
(
props
,
{
attrs
,
emit
,
slots
,
expose
})
{
const
tableElRef
=
ref
<
ComponentRef
>
(
null
);
const
tableData
=
ref
<
Recordable
[]
>
([]);
...
...
@@ -290,7 +289,7 @@
};
createTableContext
({
...
tableAction
,
wrapRef
,
getBindValues
});
useExpose
<
TableActionType
>
(
tableAction
);
expose
(
tableAction
);
emit
(
'
register
'
,
tableAction
,
formActions
);
...
...
src/components/Tree/src/Tree.vue
浏览文件 @
bd2039ac
...
...
@@ -25,7 +25,6 @@
import
{
useTree
}
from
'
./useTree
'
;
import
{
useContextMenu
}
from
'
/@/hooks/web/useContextMenu
'
;
import
{
useExpose
}
from
'
/@/hooks/core/useExpose
'
;
import
{
useDesign
}
from
'
/@/hooks/web/useDesign
'
;
import
{
basicProps
}
from
'
./props
'
;
...
...
@@ -44,7 +43,7 @@
inheritAttrs
:
false
,
props
:
basicProps
,
emits
:
[
'
update:expandedKeys
'
,
'
update:selectedKeys
'
,
'
update:value
'
,
'
change
'
,
'
check
'
],
setup
(
props
,
{
attrs
,
slots
,
emit
})
{
setup
(
props
,
{
attrs
,
slots
,
emit
,
expose
})
{
const
state
=
reactive
<
State
>
({
checkStrictly
:
props
.
checkStrictly
,
expandedKeys
:
props
.
expandedKeys
||
[],
...
...
@@ -277,7 +276,7 @@
},
};
useExpose
<
TreeActionType
>
(
instance
);
expose
(
instance
);
function
renderAction
(
node
:
TreeItem
)
{
const
{
actionList
}
=
props
;
...
...
src/components/Verify/index.ts
浏览文件 @
bd2039ac
import
{
createAsyncComponent
}
from
'
/@/utils/factory/createAsyncComponent
'
;
import
{
withInstall
}
from
'
/@/utils/index
'
;
import
basicDragVerify
from
'
./src/DragVerify.vue
'
;
import
rotateDragVerify
from
'
./src/ImgRotate.vue
'
;
export
const
BasicDragVerify
=
createAsyncComponent
(()
=>
import
(
'
./src/DragVerify
'
));
export
const
RotateDragVerify
=
createAsyncComponent
(()
=>
import
(
'
./src/ImgRotate
'
));
export
*
from
'
./src/types
'
;
export
const
BasicDragVerify
=
withInstall
(
basicDragVerify
);
export
const
RotateDragVerify
=
withInstall
(
rotateDragVerify
);
export
*
from
'
./src/typing
'
;
src/components/Verify/src/DragVerify.less
已删除
100644 → 0
浏览文件 @
3b2c40be
@radius: 4px;
.darg-verify {
position: relative;
overflow: hidden;
text-align: center;
background-color: rgb(238, 238, 238);
border: 1px solid #ddd;
border-radius: @radius;
&-bar {
position: absolute;
width: 0;
height: 36px;
background-color: @success-color;
border-radius: @radius;
&.to-left {
width: 0 !important;
transition: width 0.3s;
}
}
&-content {
position: absolute;
top: 0;
font-size: 12px;
-webkit-text-size-adjust: none;
background-color: -webkit-gradient(
linear,
left top,
right top,
color-stop(0, #333),
color-stop(0.4, #333),
color-stop(0.5, #fff),
color-stop(0.6, #333),
color-stop(1, #333)
);
animation: slidetounlock 3s infinite;
-webkit-background-clip: text;
-moz-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-text-fill-color: transparent;
&.success {
-webkit-text-fill-color: @white;
}
& > * {
-webkit-text-fill-color: #333;
}
}
&-action {
position: absolute;
top: 0;
left: 0;
display: flex;
cursor: move;
background-color: @white;
border-radius: @radius;
justify-content: center;
align-items: center;
&__icon {
cursor: inherit;
}
&.to-left {
left: 0 !important;
transition: left 0.3s;
}
}
}
@-webkit-keyframes slidetounlock {
0% {
background-position: -120px 0;
}
100% {
background-position: 120px 0;
}
}
src/components/Verify/src/DragVerify.tsx
已删除
100644 → 0
浏览文件 @
3b2c40be
import
{
defineComponent
,
ref
,
computed
,
unref
,
reactive
,
watch
,
watchEffect
}
from
'
vue
'
;
import
{
useTimeoutFn
}
from
'
/@/hooks/core/useTimeout
'
;
import
{
useEventListener
}
from
'
/@/hooks/event/useEventListener
'
;
import
{
basicProps
}
from
'
./props
'
;
import
{
getSlot
}
from
'
/@/utils/helper/tsxHelper
'
;
import
'
./DragVerify.less
'
;
import
{
CheckOutlined
,
DoubleRightOutlined
}
from
'
@ant-design/icons-vue
'
;
import
type
{
DragVerifyActionType
}
from
'
./types
'
;
import
{
useExpose
}
from
'
/@/hooks/core/useExpose
'
;
export
default
defineComponent
({
name
:
'
BaseDargVerify
'
,
props
:
basicProps
,
emits
:
[
'
success
'
,
'
update:value
'
,
'
change
'
,
'
start
'
,
'
move
'
,
'
end
'
],
setup
(
props
,
{
emit
,
slots
})
{
const
state
=
reactive
({
isMoving
:
false
,
isPassing
:
false
,
moveDistance
:
0
,
toLeft
:
false
,
startTime
:
0
,
endTime
:
0
,
});
const
wrapElRef
=
ref
<
HTMLDivElement
|
null
>
(
null
);
const
barElRef
=
ref
<
HTMLDivElement
|
null
>
(
null
);
const
contentElRef
=
ref
<
HTMLDivElement
|
null
>
(
null
);
const
actionElRef
=
ref
<
HTMLDivElement
|
null
>
(
null
);
watch
(
()
=>
state
.
isPassing
,
(
isPassing
)
=>
{
if
(
isPassing
)
{
const
{
startTime
,
endTime
}
=
state
;
const
time
=
(
endTime
-
startTime
)
/
1000
;
emit
(
'
success
'
,
{
isPassing
,
time
:
time
.
toFixed
(
1
)
});
emit
(
'
update:value
'
,
isPassing
);
emit
(
'
change
'
,
isPassing
);
}
}
);
watchEffect
(()
=>
{
state
.
isPassing
=
!!
props
.
value
;
});
const
getActionStyleRef
=
computed
(()
=>
{
const
{
height
,
actionStyle
}
=
props
;
const
h
=
`
${
parseInt
(
height
as
string
)}
px`
;
return
{
left
:
0
,
width
:
h
,
height
:
h
,
...
actionStyle
,
};
});
const
getWrapStyleRef
=
computed
(()
=>
{
const
{
height
,
width
,
circle
,
wrapStyle
}
=
props
;
const
h
=
parseInt
(
height
as
string
);
const
w
=
`
${
parseInt
(
width
as
string
)}
px`
;
return
{
width
:
w
,
height
:
`
${
h
}
px`
,
lineHeight
:
`
${
h
}
px`
,
borderRadius
:
circle
?
h
/
2
+
'
px
'
:
0
,
...
wrapStyle
,
};
});
const
getBarStyleRef
=
computed
(()
=>
{
const
{
height
,
circle
,
barStyle
}
=
props
;
const
h
=
parseInt
(
height
as
string
);
return
{
height
:
`
${
h
}
px`
,
borderRadius
:
circle
?
h
/
2
+
'
px 0 0
'
+
h
/
2
+
'
px
'
:
0
,
...
barStyle
,
};
});
const
getContentStyleRef
=
computed
(()
=>
{
const
{
height
,
width
,
contentStyle
}
=
props
;
const
h
=
`
${
parseInt
(
height
as
string
)}
px`
;
const
w
=
`
${
parseInt
(
width
as
string
)}
px`
;
return
{
height
:
h
,
width
:
w
,
...
contentStyle
,
};
});
function
getEventPageX
(
e
:
MouseEvent
|
TouchEvent
)
{
return
(
e
as
MouseEvent
).
pageX
||
(
e
as
TouchEvent
).
touches
[
0
].
pageX
;
}
useEventListener
({
el
:
document
,
name
:
'
mouseup
'
,
listener
:
()
=>
{
if
(
state
.
isMoving
)
{
resume
();
}
},
});
function
handleDragStart
(
e
:
MouseEvent
|
TouchEvent
)
{
if
(
state
.
isPassing
)
{
return
;
}
const
actionEl
=
unref
(
actionElRef
);
if
(
!
actionEl
)
return
;
emit
(
'
start
'
,
e
);
state
.
moveDistance
=
getEventPageX
(
e
)
-
parseInt
(
actionEl
.
style
.
left
.
replace
(
'
px
'
,
''
),
10
);
state
.
startTime
=
new
Date
().
getTime
();
state
.
isMoving
=
true
;
}
function
getOffset
(
el
:
HTMLDivElement
)
{
const
actionWidth
=
parseInt
(
el
.
style
.
width
);
const
{
width
}
=
props
;
const
widthNum
=
parseInt
(
width
as
string
);
const
offset
=
widthNum
-
actionWidth
-
6
;
return
{
offset
,
widthNum
,
actionWidth
};
}
function
handleDragMoving
(
e
:
MouseEvent
|
TouchEvent
)
{
const
{
isMoving
,
moveDistance
}
=
state
;
if
(
isMoving
)
{
const
actionEl
=
unref
(
actionElRef
);
const
barEl
=
unref
(
barElRef
);
if
(
!
actionEl
||
!
barEl
)
return
;
const
{
offset
,
widthNum
,
actionWidth
}
=
getOffset
(
actionEl
);
const
moveX
=
getEventPageX
(
e
)
-
moveDistance
;
emit
(
'
move
'
,
{
event
:
e
,
moveDistance
,
moveX
,
});
if
(
moveX
>
0
&&
moveX
<=
offset
)
{
actionEl
.
style
.
left
=
`
${
moveX
}
px`
;
barEl
.
style
.
width
=
`
${
moveX
+
actionWidth
/
2
}
px`
;
}
else
if
(
moveX
>
offset
)
{
actionEl
.
style
.
left
=
`
${
widthNum
-
actionWidth
}
px`
;
barEl
.
style
.
width
=
`
${
widthNum
-
actionWidth
/
2
}
px`
;
if
(
!
props
.
isSlot
)
{
checkPass
();
}
}
}
}
function
handleDragOver
(
e
:
MouseEvent
|
TouchEvent
)
{
const
{
isMoving
,
isPassing
,
moveDistance
}
=
state
;
if
(
isMoving
&&
!
isPassing
)
{
emit
(
'
end
'
,
e
);
const
actionEl
=
unref
(
actionElRef
);
const
barEl
=
unref
(
barElRef
);
if
(
!
actionEl
||
!
barEl
)
return
;
const
moveX
=
getEventPageX
(
e
)
-
moveDistance
;
const
{
offset
,
widthNum
,
actionWidth
}
=
getOffset
(
actionEl
);
if
(
moveX
<
offset
)
{
if
(
!
props
.
isSlot
)
{
resume
();
}
else
{
setTimeout
(()
=>
{
if
(
!
props
.
value
)
{
resume
();
}
else
{
const
contentEl
=
unref
(
contentElRef
);
if
(
contentEl
)
{
contentEl
.
style
.
width
=
`
${
parseInt
(
barEl
.
style
.
width
)}
px`
;
}
}
},
0
);
}
}
else
{
actionEl
.
style
.
left
=
`
${
widthNum
-
actionWidth
}
px`
;
barEl
.
style
.
width
=
`
${
widthNum
-
actionWidth
/
2
}
px`
;
checkPass
();
}
state
.
isMoving
=
false
;
}
}
function
checkPass
()
{
if
(
props
.
isSlot
)
{
resume
();
return
;
}
state
.
endTime
=
new
Date
().
getTime
();
state
.
isPassing
=
true
;
state
.
isMoving
=
false
;
}
function
resume
()
{
state
.
isMoving
=
false
;
state
.
isPassing
=
false
;
state
.
moveDistance
=
0
;
state
.
toLeft
=
false
;
state
.
startTime
=
0
;
state
.
endTime
=
0
;
const
actionEl
=
unref
(
actionElRef
);
const
barEl
=
unref
(
barElRef
);
const
contentEl
=
unref
(
contentElRef
);
if
(
!
actionEl
||
!
barEl
||
!
contentEl
)
return
;
state
.
toLeft
=
true
;
useTimeoutFn
(()
=>
{
state
.
toLeft
=
false
;
actionEl
.
style
.
left
=
'
0
'
;
barEl
.
style
.
width
=
'
0
'
;
// The time is consistent with the animation time
},
300
);
contentEl
.
style
.
width
=
unref
(
getContentStyleRef
).
width
;
}
useExpose
<
DragVerifyActionType
>
({
resume
,
});
return
()
=>
{
const
renderBar
=
()
=>
{
const
cls
=
[
`darg-verify-bar`
];
if
(
state
.
toLeft
)
{
cls
.
push
(
'
to-left
'
);
}
return
<
div
class
=
{
cls
}
ref
=
{
barElRef
}
style
=
{
unref
(
getBarStyleRef
)
}
/>;
};
const
renderContent
=
()
=>
{
const
cls
=
[
`darg-verify-content`
];
const
{
isPassing
}
=
state
;
const
{
text
,
successText
}
=
props
;
isPassing
&&
cls
.
push
(
'
success
'
);
return
(
<
div
class
=
{
cls
}
ref
=
{
contentElRef
}
style
=
{
unref
(
getContentStyleRef
)
}
>
{
getSlot
(
slots
,
'
text
'
,
isPassing
)
||
(
isPassing
?
successText
:
text
)
}
</
div
>
);
};
const
renderAction
=
()
=>
{
const
cls
=
[
`darg-verify-action`
];
const
{
toLeft
,
isPassing
}
=
state
;
if
(
toLeft
)
{
cls
.
push
(
'
to-left
'
);
}
return
(
<
div
class
=
{
cls
}
onMousedown
=
{
handleDragStart
}
onTouchstart
=
{
handleDragStart
}
style
=
{
unref
(
getActionStyleRef
)
}
ref
=
{
actionElRef
}
>
{
getSlot
(
slots
,
'
actionIcon
'
,
isPassing
)
||
(
isPassing
?
(
<
CheckOutlined
class
=
{
`darg-verify-action__icon`
}
/>
)
:
(
<
DoubleRightOutlined
class
=
{
`darg-verify-action__icon`
}
/>
))
}
</
div
>
);
};
return
(
<
div
class
=
"darg-verify"
ref
=
{
wrapElRef
}
style
=
{
unref
(
getWrapStyleRef
)
}
onMousemove
=
{
handleDragMoving
}
onTouchmove
=
{
handleDragMoving
}
onMouseleave
=
{
handleDragOver
}
onMouseup
=
{
handleDragOver
}
onTouchend
=
{
handleDragOver
}
>
{
renderBar
()
}
{
renderContent
()
}
{
renderAction
()
}
</
div
>
);
};
},
});
src/components/Verify/src/DragVerify.vue
0 → 100644
浏览文件 @
bd2039ac
<
script
lang=
"tsx"
>
import
{
defineComponent
,
ref
,
computed
,
unref
,
reactive
,
watch
,
watchEffect
}
from
'
vue
'
;
import
{
useTimeoutFn
}
from
'
/@/hooks/core/useTimeout
'
;
import
{
useEventListener
}
from
'
/@/hooks/event/useEventListener
'
;
import
{
basicProps
}
from
'
./props
'
;
import
{
getSlot
}
from
'
/@/utils/helper/tsxHelper
'
;
import
{
CheckOutlined
,
DoubleRightOutlined
}
from
'
@ant-design/icons-vue
'
;
export
default
defineComponent
({
name
:
'
BaseDargVerify
'
,
props
:
basicProps
,
emits
:
[
'
success
'
,
'
update:value
'
,
'
change
'
,
'
start
'
,
'
move
'
,
'
end
'
],
setup
(
props
,
{
emit
,
slots
,
expose
})
{
const
state
=
reactive
({
isMoving
:
false
,
isPassing
:
false
,
moveDistance
:
0
,
toLeft
:
false
,
startTime
:
0
,
endTime
:
0
,
});
const
wrapElRef
=
ref
<
HTMLDivElement
|
null
>
(
null
);
const
barElRef
=
ref
<
HTMLDivElement
|
null
>
(
null
);
const
contentElRef
=
ref
<
HTMLDivElement
|
null
>
(
null
);
const
actionElRef
=
ref
<
HTMLDivElement
|
null
>
(
null
);
useEventListener
({
el
:
document
,
name
:
'
mouseup
'
,
listener
:
()
=>
{
if
(
state
.
isMoving
)
{
resume
();
}
},
});
const
getActionStyleRef
=
computed
(()
=>
{
const
{
height
,
actionStyle
}
=
props
;
const
h
=
`
${
parseInt
(
height
as
string
)}
px`
;
return
{
left
:
0
,
width
:
h
,
height
:
h
,
...
actionStyle
,
};
});
const
getWrapStyleRef
=
computed
(()
=>
{
const
{
height
,
width
,
circle
,
wrapStyle
}
=
props
;
const
h
=
parseInt
(
height
as
string
);
const
w
=
`
${
parseInt
(
width
as
string
)}
px`
;
return
{
width
:
w
,
height
:
`
${
h
}
px`
,
lineHeight
:
`
${
h
}
px`
,
borderRadius
:
circle
?
h
/
2
+
'
px
'
:
0
,
...
wrapStyle
,
};
});
const
getBarStyleRef
=
computed
(()
=>
{
const
{
height
,
circle
,
barStyle
}
=
props
;
const
h
=
parseInt
(
height
as
string
);
return
{
height
:
`
${
h
}
px`
,
borderRadius
:
circle
?
h
/
2
+
'
px 0 0
'
+
h
/
2
+
'
px
'
:
0
,
...
barStyle
,
};
});
const
getContentStyleRef
=
computed
(()
=>
{
const
{
height
,
width
,
contentStyle
}
=
props
;
const
h
=
`
${
parseInt
(
height
as
string
)}
px`
;
const
w
=
`
${
parseInt
(
width
as
string
)}
px`
;
return
{
height
:
h
,
width
:
w
,
...
contentStyle
,
};
});
watch
(
()
=>
state
.
isPassing
,
(
isPassing
)
=>
{
if
(
isPassing
)
{
const
{
startTime
,
endTime
}
=
state
;
const
time
=
(
endTime
-
startTime
)
/
1000
;
emit
(
'
success
'
,
{
isPassing
,
time
:
time
.
toFixed
(
1
)
});
emit
(
'
update:value
'
,
isPassing
);
emit
(
'
change
'
,
isPassing
);
}
}
);
watchEffect
(()
=>
{
state
.
isPassing
=
!!
props
.
value
;
});
function
getEventPageX
(
e
:
MouseEvent
|
TouchEvent
)
{
return
(
e
as
MouseEvent
).
pageX
||
(
e
as
TouchEvent
).
touches
[
0
].
pageX
;
}
function
handleDragStart
(
e
:
MouseEvent
|
TouchEvent
)
{
if
(
state
.
isPassing
)
{
return
;
}
const
actionEl
=
unref
(
actionElRef
);
if
(
!
actionEl
)
return
;
emit
(
'
start
'
,
e
);
state
.
moveDistance
=
getEventPageX
(
e
)
-
parseInt
(
actionEl
.
style
.
left
.
replace
(
'
px
'
,
''
),
10
);
state
.
startTime
=
new
Date
().
getTime
();
state
.
isMoving
=
true
;
}
function
getOffset
(
el
:
HTMLDivElement
)
{
const
actionWidth
=
parseInt
(
el
.
style
.
width
);
const
{
width
}
=
props
;
const
widthNum
=
parseInt
(
width
as
string
);
const
offset
=
widthNum
-
actionWidth
-
6
;
return
{
offset
,
widthNum
,
actionWidth
};
}
function
handleDragMoving
(
e
:
MouseEvent
|
TouchEvent
)
{
const
{
isMoving
,
moveDistance
}
=
state
;
if
(
isMoving
)
{
const
actionEl
=
unref
(
actionElRef
);
const
barEl
=
unref
(
barElRef
);
if
(
!
actionEl
||
!
barEl
)
return
;
const
{
offset
,
widthNum
,
actionWidth
}
=
getOffset
(
actionEl
);
const
moveX
=
getEventPageX
(
e
)
-
moveDistance
;
emit
(
'
move
'
,
{
event
:
e
,
moveDistance
,
moveX
,
});
if
(
moveX
>
0
&&
moveX
<=
offset
)
{
actionEl
.
style
.
left
=
`
${
moveX
}
px`
;
barEl
.
style
.
width
=
`
${
moveX
+
actionWidth
/
2
}
px`
;
}
else
if
(
moveX
>
offset
)
{
actionEl
.
style
.
left
=
`
${
widthNum
-
actionWidth
}
px`
;
barEl
.
style
.
width
=
`
${
widthNum
-
actionWidth
/
2
}
px`
;
if
(
!
props
.
isSlot
)
{
checkPass
();
}
}
}
}
function
handleDragOver
(
e
:
MouseEvent
|
TouchEvent
)
{
const
{
isMoving
,
isPassing
,
moveDistance
}
=
state
;
if
(
isMoving
&&
!
isPassing
)
{
emit
(
'
end
'
,
e
);
const
actionEl
=
unref
(
actionElRef
);
const
barEl
=
unref
(
barElRef
);
if
(
!
actionEl
||
!
barEl
)
return
;
const
moveX
=
getEventPageX
(
e
)
-
moveDistance
;
const
{
offset
,
widthNum
,
actionWidth
}
=
getOffset
(
actionEl
);
if
(
moveX
<
offset
)
{
if
(
!
props
.
isSlot
)
{
resume
();
}
else
{
setTimeout
(()
=>
{
if
(
!
props
.
value
)
{
resume
();
}
else
{
const
contentEl
=
unref
(
contentElRef
);
if
(
contentEl
)
{
contentEl
.
style
.
width
=
`
${
parseInt
(
barEl
.
style
.
width
)}
px`
;
}
}
},
0
);
}
}
else
{
actionEl
.
style
.
left
=
`
${
widthNum
-
actionWidth
}
px`
;
barEl
.
style
.
width
=
`
${
widthNum
-
actionWidth
/
2
}
px`
;
checkPass
();
}
state
.
isMoving
=
false
;
}
}
function
checkPass
()
{
if
(
props
.
isSlot
)
{
resume
();
return
;
}
state
.
endTime
=
new
Date
().
getTime
();
state
.
isPassing
=
true
;
state
.
isMoving
=
false
;
}
function
resume
()
{
state
.
isMoving
=
false
;
state
.
isPassing
=
false
;
state
.
moveDistance
=
0
;
state
.
toLeft
=
false
;
state
.
startTime
=
0
;
state
.
endTime
=
0
;
const
actionEl
=
unref
(
actionElRef
);
const
barEl
=
unref
(
barElRef
);
const
contentEl
=
unref
(
contentElRef
);
if
(
!
actionEl
||
!
barEl
||
!
contentEl
)
return
;
state
.
toLeft
=
true
;
useTimeoutFn
(()
=>
{
state
.
toLeft
=
false
;
actionEl
.
style
.
left
=
'
0
'
;
barEl
.
style
.
width
=
'
0
'
;
// The time is consistent with the animation time
},
300
);
contentEl
.
style
.
width
=
unref
(
getContentStyleRef
).
width
;
}
expose
({
resume
,
});
return
()
=>
{
const
renderBar
=
()
=>
{
const
cls
=
[
`darg-verify-bar`
];
if
(
state
.
toLeft
)
{
cls
.
push
(
'
to-left
'
);
}
return
<
div
class
=
{
cls
}
ref
=
{
barElRef
}
style
=
{
unref
(
getBarStyleRef
)}
/>
;
};
const
renderContent
=
()
=>
{
const
cls
=
[
`darg-verify-content`
];
const
{
isPassing
}
=
state
;
const
{
text
,
successText
}
=
props
;
isPassing
&&
cls
.
push
(
'
success
'
);
return
(
<
div
class
=
{
cls
}
ref
=
{
contentElRef
}
style
=
{
unref
(
getContentStyleRef
)}
>
{
getSlot
(
slots
,
'
text
'
,
isPassing
)
||
(
isPassing
?
successText
:
text
)}
<
/div
>
);
};
const
renderAction
=
()
=>
{
const
cls
=
[
`darg-verify-action`
];
const
{
toLeft
,
isPassing
}
=
state
;
if
(
toLeft
)
{
cls
.
push
(
'
to-left
'
);
}
return
(
<
div
class
=
{
cls
}
onMousedown
=
{
handleDragStart
}
onTouchstart
=
{
handleDragStart
}
style
=
{
unref
(
getActionStyleRef
)}
ref
=
{
actionElRef
}
>
{
getSlot
(
slots
,
'
actionIcon
'
,
isPassing
)
||
(
isPassing
?
(
<
CheckOutlined
class
=
{
`darg-verify-action__icon`
}
/
>
)
:
(
<
DoubleRightOutlined
class
=
{
`darg-verify-action__icon`
}
/
>
))}
<
/div
>
);
};
return
(
<
div
class
=
"
darg-verify
"
ref
=
{
wrapElRef
}
style
=
{
unref
(
getWrapStyleRef
)}
onMousemove
=
{
handleDragMoving
}
onTouchmove
=
{
handleDragMoving
}
onMouseleave
=
{
handleDragOver
}
onMouseup
=
{
handleDragOver
}
onTouchend
=
{
handleDragOver
}
>
{
renderBar
()}
{
renderContent
()}
{
renderAction
()}
<
/div
>
);
};
},
});
</
script
>
<
style
lang=
"less"
>
@radius: 4px;
.darg-verify {
position: relative;
overflow: hidden;
text-align: center;
background-color: rgb(238, 238, 238);
border: 1px solid #ddd;
border-radius: @radius;
&-bar {
position: absolute;
width: 0;
height: 36px;
background-color: @success-color;
border-radius: @radius;
&.to-left {
width: 0 !important;
transition: width 0.3s;
}
}
&-content {
position: absolute;
top: 0;
font-size: 12px;
-webkit-text-size-adjust: none;
background-color: -webkit-gradient(
linear,
left top,
right top,
color-stop(0, #333),
color-stop(0.4, #333),
color-stop(0.5, #fff),
color-stop(0.6, #333),
color-stop(1, #333)
);
animation: slidetounlock 3s infinite;
-webkit-background-clip: text;
-moz-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-text-fill-color: transparent;
&.success {
-webkit-text-fill-color: @white;
}
& > * {
-webkit-text-fill-color: #333;
}
}
&-action {
position: absolute;
top: 0;
left: 0;
display: flex;
cursor: move;
background-color: @white;
border-radius: @radius;
justify-content: center;
align-items: center;
&__icon {
cursor: inherit;
}
&.to-left {
left: 0 !important;
transition: left 0.3s;
}
}
}
@-webkit-keyframes slidetounlock {
0% {
background-position: -120px 0;
}
100% {
background-position: 120px 0;
}
}
</
style
>
src/components/Verify/src/ImgRotate.less
已删除
100644 → 0
浏览文件 @
3b2c40be
.ir-dv {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
&-img__wrap {
position: relative;
overflow: hidden;
border-radius: 50%;
img {
width: 100%;
border-radius: 50%;
&.to-origin {
transition: transform 0.3s;
}
}
}
&-img__tip {
position: absolute;
bottom: 10px;
left: 0;
z-index: 1;
display: block;
width: 100%;
height: 30px;
font-size: 12px;
line-height: 30px;
color: @white;
text-align: center;
&.success {
background-color: fade(@success-color, 60%);
}
&.error {
background-color: fade(@error-color, 60%);
}
&.normal {
background-color: rgba(0, 0, 0, 0.3);
}
}
&-drag__bar {
margin-top: 20px;
}
}
src/components/Verify/src/ImgRotate.tsx
已删除
100644 → 0
浏览文件 @
3b2c40be
import
'
./ImgRotate.less
'
;
import
type
{
MoveData
,
DragVerifyActionType
}
from
'
./types
'
;
import
{
defineComponent
,
computed
,
unref
,
reactive
,
watch
,
ref
,
getCurrentInstance
}
from
'
vue
'
;
import
{
useTimeoutFn
}
from
'
/@/hooks/core/useTimeout
'
;
import
BasicDragVerify
from
'
./DragVerify
'
;
import
{
hackCss
}
from
'
/@/utils/domUtils
'
;
import
{
rotateProps
}
from
'
./props
'
;
import
{
useI18n
}
from
'
/@/hooks/web/useI18n
'
;
export
default
defineComponent
({
name
:
'
ImgRotateDargVerify
'
,
inheritAttrs
:
false
,
props
:
rotateProps
,
emits
:
[
'
success
'
,
'
change
'
,
'
update:value
'
],
setup
(
props
,
{
emit
,
attrs
})
{
const
basicRef
=
ref
<
Nullable
<
DragVerifyActionType
>>
(
null
);
const
state
=
reactive
({
showTip
:
false
,
isPassing
:
false
,
imgStyle
:
{},
randomRotate
:
0
,
currentRotate
:
0
,
toOrigin
:
false
,
startTime
:
0
,
endTime
:
0
,
draged
:
false
,
});
const
{
t
}
=
useI18n
();
watch
(
()
=>
state
.
isPassing
,
(
isPassing
)
=>
{
if
(
isPassing
)
{
const
{
startTime
,
endTime
}
=
state
;
const
time
=
(
endTime
-
startTime
)
/
1000
;
emit
(
'
success
'
,
{
isPassing
,
time
:
time
.
toFixed
(
1
)
});
emit
(
'
change
'
,
isPassing
);
emit
(
'
update:value
'
,
isPassing
);
}
}
);
const
getImgWrapStyleRef
=
computed
(()
=>
{
const
{
imgWrapStyle
,
imgWidth
}
=
props
;
return
{
width
:
`
${
imgWidth
}
px`
,
height
:
`
${
imgWidth
}
px`
,
...
imgWrapStyle
,
};
});
const
getFactorRef
=
computed
(()
=>
{
const
{
minDegree
,
maxDegree
}
=
props
;
if
(
minDegree
===
maxDegree
)
{
return
Math
.
floor
(
1
+
Math
.
random
()
*
1
)
/
10
+
1
;
}
return
1
;
});
function
handleStart
()
{
state
.
startTime
=
new
Date
().
getTime
();
}
function
handleDragBarMove
(
data
:
MoveData
)
{
state
.
draged
=
true
;
const
{
imgWidth
,
height
,
maxDegree
}
=
props
;
const
{
moveX
}
=
data
;
const
currentRotate
=
Math
.
ceil
(
(
moveX
/
(
imgWidth
!
-
parseInt
(
height
as
string
)))
*
maxDegree
!
*
unref
(
getFactorRef
)
);
state
.
currentRotate
=
currentRotate
;
state
.
imgStyle
=
hackCss
(
'
transform
'
,
`rotateZ(
${
state
.
randomRotate
-
currentRotate
}
deg)`
);
}
function
handleImgOnLoad
()
{
const
{
minDegree
,
maxDegree
}
=
props
;
const
ranRotate
=
Math
.
floor
(
minDegree
!
+
Math
.
random
()
*
(
maxDegree
!
-
minDegree
!
));
// 生成随机角度
state
.
randomRotate
=
ranRotate
;
state
.
imgStyle
=
hackCss
(
'
transform
'
,
`rotateZ(
${
ranRotate
}
deg)`
);
}
function
handleDragEnd
()
{
const
{
randomRotate
,
currentRotate
}
=
state
;
const
{
diffDegree
}
=
props
;
if
(
Math
.
abs
(
randomRotate
-
currentRotate
)
>=
(
diffDegree
||
20
))
{
state
.
imgStyle
=
hackCss
(
'
transform
'
,
`rotateZ(
${
randomRotate
}
deg)`
);
state
.
toOrigin
=
true
;
useTimeoutFn
(()
=>
{
state
.
toOrigin
=
false
;
state
.
showTip
=
true
;
// 时间与动画时间保持一致
},
300
);
}
else
{
checkPass
();
}
state
.
showTip
=
true
;
}
function
checkPass
()
{
state
.
isPassing
=
true
;
state
.
endTime
=
new
Date
().
getTime
();
}
function
resume
()
{
state
.
showTip
=
false
;
const
basicEl
=
unref
(
basicRef
);
if
(
!
basicEl
)
{
return
;
}
state
.
isPassing
=
false
;
basicEl
.
resume
();
handleImgOnLoad
();
}
const
instance
=
getCurrentInstance
()
as
any
;
if
(
instance
)
{
instance
.
resume
=
resume
;
}
// handleImgOnLoad();
return
()
=>
{
const
{
src
}
=
props
;
const
{
toOrigin
,
isPassing
,
startTime
,
endTime
}
=
state
;
const
imgCls
:
string
[]
=
[];
if
(
toOrigin
)
{
imgCls
.
push
(
'
to-origin
'
);
}
const
time
=
(
endTime
-
startTime
)
/
1000
;
return
(
<
div
class
=
"ir-dv"
>
<
div
class
=
{
`ir-dv-img__wrap`
}
style
=
{
unref
(
getImgWrapStyleRef
)
}
>
<
img
src
=
{
src
}
onLoad
=
{
handleImgOnLoad
}
width
=
{
parseInt
(
props
.
width
as
string
)
}
class
=
{
imgCls
}
style
=
{
state
.
imgStyle
}
onClick
=
{
()
=>
{
resume
();
}
}
/>
{
state
.
showTip
&&
(
<
span
class
=
{
[
`ir-dv-img__tip`
,
state
.
isPassing
?
'
success
'
:
'
error
'
]
}
>
{
state
.
isPassing
?
t
(
'
component.verify.time
'
,
{
time
:
time
.
toFixed
(
1
)
})
:
t
(
'
component.verify.error
'
)
}
</
span
>
)
}
{
!
state
.
showTip
&&
!
state
.
draged
&&
(
<
span
class
=
{
[
`ir-dv-img__tip`
,
'
normal
'
]
}
>
{
t
(
'
component.verify.redoTip
'
)
}
</
span
>
)
}
</
div
>
<
BasicDragVerify
class
=
{
`ir-dv-drag__bar`
}
onMove
=
{
handleDragBarMove
}
onEnd
=
{
handleDragEnd
}
onStart
=
{
handleStart
}
ref
=
{
basicRef
}
{
...{
...
attrs
,
...
props
}
}
value
=
{
isPassing
}
isSlot
=
{
true
}
/>
</
div
>
);
};
},
});
src/components/Verify/src/ImgRotate.vue
0 → 100644
浏览文件 @
bd2039ac
<
script
lang=
"tsx"
>
import
type
{
MoveData
,
DragVerifyActionType
}
from
'
./typing
'
;
import
{
defineComponent
,
computed
,
unref
,
reactive
,
watch
,
ref
,
getCurrentInstance
}
from
'
vue
'
;
import
{
useTimeoutFn
}
from
'
/@/hooks/core/useTimeout
'
;
import
BasicDragVerify
from
'
./DragVerify.vue
'
;
import
{
hackCss
}
from
'
/@/utils/domUtils
'
;
import
{
rotateProps
}
from
'
./props
'
;
import
{
useI18n
}
from
'
/@/hooks/web/useI18n
'
;
export
default
defineComponent
({
name
:
'
ImgRotateDargVerify
'
,
inheritAttrs
:
false
,
props
:
rotateProps
,
emits
:
[
'
success
'
,
'
change
'
,
'
update:value
'
],
setup
(
props
,
{
emit
,
attrs
})
{
const
basicRef
=
ref
<
Nullable
<
DragVerifyActionType
>>
(
null
);
const
state
=
reactive
({
showTip
:
false
,
isPassing
:
false
,
imgStyle
:
{},
randomRotate
:
0
,
currentRotate
:
0
,
toOrigin
:
false
,
startTime
:
0
,
endTime
:
0
,
draged
:
false
,
});
const
{
t
}
=
useI18n
();
watch
(
()
=>
state
.
isPassing
,
(
isPassing
)
=>
{
if
(
isPassing
)
{
const
{
startTime
,
endTime
}
=
state
;
const
time
=
(
endTime
-
startTime
)
/
1000
;
emit
(
'
success
'
,
{
isPassing
,
time
:
time
.
toFixed
(
1
)
});
emit
(
'
change
'
,
isPassing
);
emit
(
'
update:value
'
,
isPassing
);
}
}
);
const
getImgWrapStyleRef
=
computed
(()
=>
{
const
{
imgWrapStyle
,
imgWidth
}
=
props
;
return
{
width
:
`
${
imgWidth
}
px`
,
height
:
`
${
imgWidth
}
px`
,
...
imgWrapStyle
,
};
});
const
getFactorRef
=
computed
(()
=>
{
const
{
minDegree
,
maxDegree
}
=
props
;
if
(
minDegree
===
maxDegree
)
{
return
Math
.
floor
(
1
+
Math
.
random
()
*
1
)
/
10
+
1
;
}
return
1
;
});
function
handleStart
()
{
state
.
startTime
=
new
Date
().
getTime
();
}
function
handleDragBarMove
(
data
:
MoveData
)
{
state
.
draged
=
true
;
const
{
imgWidth
,
height
,
maxDegree
}
=
props
;
const
{
moveX
}
=
data
;
const
currentRotate
=
Math
.
ceil
(
(
moveX
/
(
imgWidth
!
-
parseInt
(
height
as
string
)))
*
maxDegree
!
*
unref
(
getFactorRef
)
);
state
.
currentRotate
=
currentRotate
;
state
.
imgStyle
=
hackCss
(
'
transform
'
,
`rotateZ(
${
state
.
randomRotate
-
currentRotate
}
deg)`
);
}
function
handleImgOnLoad
()
{
const
{
minDegree
,
maxDegree
}
=
props
;
const
ranRotate
=
Math
.
floor
(
minDegree
!
+
Math
.
random
()
*
(
maxDegree
!
-
minDegree
!
));
// 生成随机角度
state
.
randomRotate
=
ranRotate
;
state
.
imgStyle
=
hackCss
(
'
transform
'
,
`rotateZ(
${
ranRotate
}
deg)`
);
}
function
handleDragEnd
()
{
const
{
randomRotate
,
currentRotate
}
=
state
;
const
{
diffDegree
}
=
props
;
if
(
Math
.
abs
(
randomRotate
-
currentRotate
)
>=
(
diffDegree
||
20
))
{
state
.
imgStyle
=
hackCss
(
'
transform
'
,
`rotateZ(
${
randomRotate
}
deg)`
);
state
.
toOrigin
=
true
;
useTimeoutFn
(()
=>
{
state
.
toOrigin
=
false
;
state
.
showTip
=
true
;
// 时间与动画时间保持一致
},
300
);
}
else
{
checkPass
();
}
state
.
showTip
=
true
;
}
function
checkPass
()
{
state
.
isPassing
=
true
;
state
.
endTime
=
new
Date
().
getTime
();
}
function
resume
()
{
state
.
showTip
=
false
;
const
basicEl
=
unref
(
basicRef
);
if
(
!
basicEl
)
{
return
;
}
state
.
isPassing
=
false
;
basicEl
.
resume
();
handleImgOnLoad
();
}
const
instance
=
getCurrentInstance
()
as
any
;
if
(
instance
)
{
instance
.
resume
=
resume
;
}
// handleImgOnLoad();
return
()
=>
{
const
{
src
}
=
props
;
const
{
toOrigin
,
isPassing
,
startTime
,
endTime
}
=
state
;
const
imgCls
:
string
[]
=
[];
if
(
toOrigin
)
{
imgCls
.
push
(
'
to-origin
'
);
}
const
time
=
(
endTime
-
startTime
)
/
1000
;
return
(
<
div
class
=
"
ir-dv
"
>
<
div
class
=
{
`ir-dv-img__wrap`
}
style
=
{
unref
(
getImgWrapStyleRef
)}
>
<
img
src
=
{
src
}
onLoad
=
{
handleImgOnLoad
}
width
=
{
parseInt
(
props
.
width
as
string
)}
class
=
{
imgCls
}
style
=
{
state
.
imgStyle
}
onClick
=
{()
=>
{
resume
();
}}
/
>
{
state
.
showTip
&&
(
<
span
class
=
{[
`ir-dv-img__tip`
,
state
.
isPassing
?
'
success
'
:
'
error
'
]}
>
{
state
.
isPassing
?
t
(
'
component.verify.time
'
,
{
time
:
time
.
toFixed
(
1
)
})
:
t
(
'
component.verify.error
'
)}
<
/span
>
)}
{
!
state
.
showTip
&&
!
state
.
draged
&&
(
<
span
class
=
{[
`ir-dv-img__tip`
,
'
normal
'
]}
>
{
t
(
'
component.verify.redoTip
'
)}
<
/span
>
)}
<
/div
>
<
BasicDragVerify
class
=
{
`ir-dv-drag__bar`
}
onMove
=
{
handleDragBarMove
}
onEnd
=
{
handleDragEnd
}
onStart
=
{
handleStart
}
ref
=
{
basicRef
}
{...{
...
attrs
,
...
props
}}
value
=
{
isPassing
}
isSlot
=
{
true
}
/
>
<
/div
>
);
};
},
});
</
script
>
<
style
lang=
"less"
>
.ir-dv {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
&-img__wrap {
position: relative;
overflow: hidden;
border-radius: 50%;
img {
width: 100%;
border-radius: 50%;
&.to-origin {
transition: transform 0.3s;
}
}
}
&-img__tip {
position: absolute;
bottom: 10px;
left: 0;
z-index: 1;
display: block;
width: 100%;
height: 30px;
font-size: 12px;
line-height: 30px;
color: @white;
text-align: center;
&.success {
background-color: fade(@success-color, 60%);
}
&.error {
background-color: fade(@error-color, 60%);
}
&.normal {
background-color: rgba(0, 0, 0, 0.3);
}
}
&-drag__bar {
margin-top: 20px;
}
}
</
style
>
src/components/Verify/src/typ
es
.ts
→
src/components/Verify/src/typ
ing
.ts
浏览文件 @
bd2039ac
文件已移动
src/hooks/core/useExpose.ts
已删除
100644 → 0
浏览文件 @
3b2c40be
import
{
getCurrentInstance
}
from
'
vue
'
;
// expose public api
export
function
useExpose
<
T
>
(
apis
:
T
)
{
const
instance
=
getCurrentInstance
();
if
(
instance
)
{
Object
.
assign
(
instance
.
proxy
,
apis
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录