Commit bd2039accbc99cdfddbea62a63c3704e58034873

Authored by Vben
1 parent 3b2c40be

refactor: remove useExpose

CHANGELOG.zh_CN.md
1 1 ## Wip
2 2  
  3 +### ✨ Refactor
  4 +
  5 +- 移除`useExpose`,使用组件自身提供的`expose`代替
  6 +
3 7 ### ✨ Features
4 8  
5 9 - **CropperImage** `Cropper` 头像裁剪新增圆形裁剪功能
... ...
src/components/Table/src/BasicTable.vue
... ... @@ -59,7 +59,6 @@
59 59 import { createTableContext } from './hooks/useTableContext';
60 60 import { useTableFooter } from './hooks/useTableFooter';
61 61 import { useTableForm } from './hooks/useTableForm';
62   - import { useExpose } from '/@/hooks/core/useExpose';
63 62 import { useDesign } from '/@/hooks/web/useDesign';
64 63  
65 64 import { omit } from 'lodash-es';
... ... @@ -91,7 +90,7 @@
91 90 'change',
92 91 'columns-change',
93 92 ],
94   - setup(props, { attrs, emit, slots }) {
  93 + setup(props, { attrs, emit, slots, expose }) {
95 94 const tableElRef = ref<ComponentRef>(null);
96 95 const tableData = ref<Recordable[]>([]);
97 96  
... ... @@ -290,7 +289,7 @@
290 289 };
291 290 createTableContext({ ...tableAction, wrapRef, getBindValues });
292 291  
293   - useExpose<TableActionType>(tableAction);
  292 + expose(tableAction);
294 293  
295 294 emit('register', tableAction, formActions);
296 295  
... ...
src/components/Tree/src/Tree.vue
... ... @@ -25,7 +25,6 @@
25 25  
26 26 import { useTree } from './useTree';
27 27 import { useContextMenu } from '/@/hooks/web/useContextMenu';
28   - import { useExpose } from '/@/hooks/core/useExpose';
29 28 import { useDesign } from '/@/hooks/web/useDesign';
30 29  
31 30 import { basicProps } from './props';
... ... @@ -44,7 +43,7 @@
44 43 inheritAttrs: false,
45 44 props: basicProps,
46 45 emits: ['update:expandedKeys', 'update:selectedKeys', 'update:value', 'change', 'check'],
47   - setup(props, { attrs, slots, emit }) {
  46 + setup(props, { attrs, slots, emit, expose }) {
48 47 const state = reactive<State>({
49 48 checkStrictly: props.checkStrictly,
50 49 expandedKeys: props.expandedKeys || [],
... ... @@ -277,7 +276,7 @@
277 276 },
278 277 };
279 278  
280   - useExpose<TreeActionType>(instance);
  279 + expose(instance);
281 280  
282 281 function renderAction(node: TreeItem) {
283 282 const { actionList } = props;
... ...
src/components/Verify/index.ts
1   -import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
  1 +import { withInstall } from '/@/utils/index';
  2 +import basicDragVerify from './src/DragVerify.vue';
  3 +import rotateDragVerify from './src/ImgRotate.vue';
2 4  
3   -export const BasicDragVerify = createAsyncComponent(() => import('./src/DragVerify'));
4   -export const RotateDragVerify = createAsyncComponent(() => import('./src/ImgRotate'));
5   -
6   -export * from './src/types';
  5 +export const BasicDragVerify = withInstall(basicDragVerify);
  6 +export const RotateDragVerify = withInstall(rotateDragVerify);
  7 +export * from './src/typing';
... ...
src/components/Verify/src/DragVerify.less deleted 100644 → 0
1   -@radius: 4px;
2   -
3   -.darg-verify {
4   - position: relative;
5   - overflow: hidden;
6   - text-align: center;
7   - background-color: rgb(238, 238, 238);
8   - border: 1px solid #ddd;
9   - border-radius: @radius;
10   -
11   - &-bar {
12   - position: absolute;
13   - width: 0;
14   - height: 36px;
15   - background-color: @success-color;
16   - border-radius: @radius;
17   -
18   - &.to-left {
19   - width: 0 !important;
20   - transition: width 0.3s;
21   - }
22   - }
23   -
24   - &-content {
25   - position: absolute;
26   - top: 0;
27   - font-size: 12px;
28   - -webkit-text-size-adjust: none;
29   - background-color: -webkit-gradient(
30   - linear,
31   - left top,
32   - right top,
33   - color-stop(0, #333),
34   - color-stop(0.4, #333),
35   - color-stop(0.5, #fff),
36   - color-stop(0.6, #333),
37   - color-stop(1, #333)
38   - );
39   - animation: slidetounlock 3s infinite;
40   - -webkit-background-clip: text;
41   - -moz-user-select: none;
42   - -webkit-user-select: none;
43   - -o-user-select: none;
44   - -ms-user-select: none;
45   - user-select: none;
46   - -webkit-text-fill-color: transparent;
47   -
48   - &.success {
49   - -webkit-text-fill-color: @white;
50   - }
51   -
52   - & > * {
53   - -webkit-text-fill-color: #333;
54   - }
55   - }
56   -
57   - &-action {
58   - position: absolute;
59   - top: 0;
60   - left: 0;
61   - display: flex;
62   - cursor: move;
63   - background-color: @white;
64   - border-radius: @radius;
65   - justify-content: center;
66   - align-items: center;
67   -
68   - &__icon {
69   - cursor: inherit;
70   - }
71   -
72   - &.to-left {
73   - left: 0 !important;
74   - transition: left 0.3s;
75   - }
76   - }
77   -}
78   -
79   -@-webkit-keyframes slidetounlock {
80   - 0% {
81   - background-position: -120px 0;
82   - }
83   -
84   - 100% {
85   - background-position: 120px 0;
86   - }
87   -}
src/components/Verify/src/DragVerify.tsx renamed to src/components/Verify/src/DragVerify.vue
1   -import { defineComponent, ref, computed, unref, reactive, watch, watchEffect } from 'vue';
2   -import { useTimeoutFn } from '/@/hooks/core/useTimeout';
3   -import { useEventListener } from '/@/hooks/event/useEventListener';
4   -import { basicProps } from './props';
5   -import { getSlot } from '/@/utils/helper/tsxHelper';
6   -import './DragVerify.less';
7   -import { CheckOutlined, DoubleRightOutlined } from '@ant-design/icons-vue';
8   -import type { DragVerifyActionType } from './types';
9   -import { useExpose } from '/@/hooks/core/useExpose';
10   -export default defineComponent({
11   - name: 'BaseDargVerify',
12   - props: basicProps,
13   - emits: ['success', 'update:value', 'change', 'start', 'move', 'end'],
14   - setup(props, { emit, slots }) {
15   - const state = reactive({
16   - isMoving: false,
17   - isPassing: false,
18   - moveDistance: 0,
19   - toLeft: false,
20   - startTime: 0,
21   - endTime: 0,
22   - });
23   -
24   - const wrapElRef = ref<HTMLDivElement | null>(null);
25   - const barElRef = ref<HTMLDivElement | null>(null);
26   - const contentElRef = ref<HTMLDivElement | null>(null);
27   - const actionElRef = ref<HTMLDivElement | null>(null);
28   -
29   - watch(
30   - () => state.isPassing,
31   - (isPassing) => {
32   - if (isPassing) {
33   - const { startTime, endTime } = state;
34   - const time = (endTime - startTime) / 1000;
35   - emit('success', { isPassing, time: time.toFixed(1) });
36   - emit('update:value', isPassing);
37   - emit('change', isPassing);
38   - }
39   - }
40   - );
41   -
42   - watchEffect(() => {
43   - state.isPassing = !!props.value;
44   - });
45   -
46   - const getActionStyleRef = computed(() => {
47   - const { height, actionStyle } = props;
48   - const h = `${parseInt(height as string)}px`;
49   - return {
50   - left: 0,
51   - width: h,
52   - height: h,
53   - ...actionStyle,
54   - };
55   - });
56   - const getWrapStyleRef = computed(() => {
57   - const { height, width, circle, wrapStyle } = props;
58   - const h = parseInt(height as string);
59   - const w = `${parseInt(width as string)}px`;
60   - return {
61   - width: w,
62   - height: `${h}px`,
63   - lineHeight: `${h}px`,
64   - borderRadius: circle ? h / 2 + 'px' : 0,
65   - ...wrapStyle,
66   - };
67   - });
68   -
69   - const getBarStyleRef = computed(() => {
70   - const { height, circle, barStyle } = props;
71   - const h = parseInt(height as string);
72   - return {
73   - height: `${h}px`,
74   - borderRadius: circle ? h / 2 + 'px 0 0 ' + h / 2 + 'px' : 0,
75   - ...barStyle,
76   - };
77   - });
  1 +<script lang="tsx">
  2 + import { defineComponent, ref, computed, unref, reactive, watch, watchEffect } from 'vue';
  3 + import { useTimeoutFn } from '/@/hooks/core/useTimeout';
  4 + import { useEventListener } from '/@/hooks/event/useEventListener';
  5 + import { basicProps } from './props';
  6 + import { getSlot } from '/@/utils/helper/tsxHelper';
  7 + import { CheckOutlined, DoubleRightOutlined } from '@ant-design/icons-vue';
78 8  
79   - const getContentStyleRef = computed(() => {
80   - const { height, width, contentStyle } = props;
81   - const h = `${parseInt(height as string)}px`;
82   - const w = `${parseInt(width as string)}px`;
  9 + export default defineComponent({
  10 + name: 'BaseDargVerify',
  11 + props: basicProps,
  12 + emits: ['success', 'update:value', 'change', 'start', 'move', 'end'],
  13 + setup(props, { emit, slots, expose }) {
  14 + const state = reactive({
  15 + isMoving: false,
  16 + isPassing: false,
  17 + moveDistance: 0,
  18 + toLeft: false,
  19 + startTime: 0,
  20 + endTime: 0,
  21 + });
83 22  
84   - return {
85   - height: h,
86   - width: w,
87   - ...contentStyle,
88   - };
89   - });
  23 + const wrapElRef = ref<HTMLDivElement | null>(null);
  24 + const barElRef = ref<HTMLDivElement | null>(null);
  25 + const contentElRef = ref<HTMLDivElement | null>(null);
  26 + const actionElRef = ref<HTMLDivElement | null>(null);
90 27  
91   - function getEventPageX(e: MouseEvent | TouchEvent) {
92   - return (e as MouseEvent).pageX || (e as TouchEvent).touches[0].pageX;
93   - }
  28 + useEventListener({
  29 + el: document,
  30 + name: 'mouseup',
  31 + listener: () => {
  32 + if (state.isMoving) {
  33 + resume();
  34 + }
  35 + },
  36 + });
94 37  
95   - useEventListener({
96   - el: document,
97   - name: 'mouseup',
98   - listener: () => {
99   - if (state.isMoving) {
100   - resume();
  38 + const getActionStyleRef = computed(() => {
  39 + const { height, actionStyle } = props;
  40 + const h = `${parseInt(height as string)}px`;
  41 + return {
  42 + left: 0,
  43 + width: h,
  44 + height: h,
  45 + ...actionStyle,
  46 + };
  47 + });
  48 +
  49 + const getWrapStyleRef = computed(() => {
  50 + const { height, width, circle, wrapStyle } = props;
  51 + const h = parseInt(height as string);
  52 + const w = `${parseInt(width as string)}px`;
  53 + return {
  54 + width: w,
  55 + height: `${h}px`,
  56 + lineHeight: `${h}px`,
  57 + borderRadius: circle ? h / 2 + 'px' : 0,
  58 + ...wrapStyle,
  59 + };
  60 + });
  61 +
  62 + const getBarStyleRef = computed(() => {
  63 + const { height, circle, barStyle } = props;
  64 + const h = parseInt(height as string);
  65 + return {
  66 + height: `${h}px`,
  67 + borderRadius: circle ? h / 2 + 'px 0 0 ' + h / 2 + 'px' : 0,
  68 + ...barStyle,
  69 + };
  70 + });
  71 +
  72 + const getContentStyleRef = computed(() => {
  73 + const { height, width, contentStyle } = props;
  74 + const h = `${parseInt(height as string)}px`;
  75 + const w = `${parseInt(width as string)}px`;
  76 +
  77 + return {
  78 + height: h,
  79 + width: w,
  80 + ...contentStyle,
  81 + };
  82 + });
  83 +
  84 + watch(
  85 + () => state.isPassing,
  86 + (isPassing) => {
  87 + if (isPassing) {
  88 + const { startTime, endTime } = state;
  89 + const time = (endTime - startTime) / 1000;
  90 + emit('success', { isPassing, time: time.toFixed(1) });
  91 + emit('update:value', isPassing);
  92 + emit('change', isPassing);
  93 + }
101 94 }
102   - },
103   - });
104   - function handleDragStart(e: MouseEvent | TouchEvent) {
105   - if (state.isPassing) {
106   - return;
  95 + );
  96 +
  97 + watchEffect(() => {
  98 + state.isPassing = !!props.value;
  99 + });
  100 +
  101 + function getEventPageX(e: MouseEvent | TouchEvent) {
  102 + return (e as MouseEvent).pageX || (e as TouchEvent).touches[0].pageX;
107 103 }
108 104  
109   - const actionEl = unref(actionElRef);
110   - if (!actionEl) return;
111   - emit('start', e);
112   - state.moveDistance = getEventPageX(e) - parseInt(actionEl.style.left.replace('px', ''), 10);
113   - state.startTime = new Date().getTime();
114   - state.isMoving = true;
115   - }
116   - function getOffset(el: HTMLDivElement) {
117   - const actionWidth = parseInt(el.style.width);
118   - const { width } = props;
119   - const widthNum = parseInt(width as string);
120   - const offset = widthNum - actionWidth - 6;
121   - return { offset, widthNum, actionWidth };
122   - }
123   - function handleDragMoving(e: MouseEvent | TouchEvent) {
124   - const { isMoving, moveDistance } = state;
125   - if (isMoving) {
  105 + function handleDragStart(e: MouseEvent | TouchEvent) {
  106 + if (state.isPassing) {
  107 + return;
  108 + }
126 109 const actionEl = unref(actionElRef);
127   - const barEl = unref(barElRef);
128   - if (!actionEl || !barEl) return;
129   - const { offset, widthNum, actionWidth } = getOffset(actionEl);
130   - const moveX = getEventPageX(e) - moveDistance;
131   -
132   - emit('move', {
133   - event: e,
134   - moveDistance,
135   - moveX,
136   - });
137   - if (moveX > 0 && moveX <= offset) {
138   - actionEl.style.left = `${moveX}px`;
139   - barEl.style.width = `${moveX + actionWidth / 2}px`;
140   - } else if (moveX > offset) {
141   - actionEl.style.left = `${widthNum - actionWidth}px`;
142   - barEl.style.width = `${widthNum - actionWidth / 2}px`;
143   - if (!props.isSlot) {
144   - checkPass();
  110 + if (!actionEl) return;
  111 + emit('start', e);
  112 + state.moveDistance = getEventPageX(e) - parseInt(actionEl.style.left.replace('px', ''), 10);
  113 + state.startTime = new Date().getTime();
  114 + state.isMoving = true;
  115 + }
  116 +
  117 + function getOffset(el: HTMLDivElement) {
  118 + const actionWidth = parseInt(el.style.width);
  119 + const { width } = props;
  120 + const widthNum = parseInt(width as string);
  121 + const offset = widthNum - actionWidth - 6;
  122 + return { offset, widthNum, actionWidth };
  123 + }
  124 +
  125 + function handleDragMoving(e: MouseEvent | TouchEvent) {
  126 + const { isMoving, moveDistance } = state;
  127 + if (isMoving) {
  128 + const actionEl = unref(actionElRef);
  129 + const barEl = unref(barElRef);
  130 + if (!actionEl || !barEl) return;
  131 + const { offset, widthNum, actionWidth } = getOffset(actionEl);
  132 + const moveX = getEventPageX(e) - moveDistance;
  133 +
  134 + emit('move', {
  135 + event: e,
  136 + moveDistance,
  137 + moveX,
  138 + });
  139 + if (moveX > 0 && moveX <= offset) {
  140 + actionEl.style.left = `${moveX}px`;
  141 + barEl.style.width = `${moveX + actionWidth / 2}px`;
  142 + } else if (moveX > offset) {
  143 + actionEl.style.left = `${widthNum - actionWidth}px`;
  144 + barEl.style.width = `${widthNum - actionWidth / 2}px`;
  145 + if (!props.isSlot) {
  146 + checkPass();
  147 + }
145 148 }
146 149 }
147 150 }
148   - }
149 151  
150   - function handleDragOver(e: MouseEvent | TouchEvent) {
151   - const { isMoving, isPassing, moveDistance } = state;
152   - if (isMoving && !isPassing) {
153   - emit('end', e);
154   - const actionEl = unref(actionElRef);
155   - const barEl = unref(barElRef);
156   - if (!actionEl || !barEl) return;
157   - const moveX = getEventPageX(e) - moveDistance;
158   - const { offset, widthNum, actionWidth } = getOffset(actionEl);
159   - if (moveX < offset) {
160   - if (!props.isSlot) {
161   - resume();
162   - } else {
163   - setTimeout(() => {
164   - if (!props.value) {
165   - resume();
166   - } else {
167   - const contentEl = unref(contentElRef);
168   - if (contentEl) {
169   - contentEl.style.width = `${parseInt(barEl.style.width)}px`;
  152 + function handleDragOver(e: MouseEvent | TouchEvent) {
  153 + const { isMoving, isPassing, moveDistance } = state;
  154 + if (isMoving && !isPassing) {
  155 + emit('end', e);
  156 + const actionEl = unref(actionElRef);
  157 + const barEl = unref(barElRef);
  158 + if (!actionEl || !barEl) return;
  159 + const moveX = getEventPageX(e) - moveDistance;
  160 + const { offset, widthNum, actionWidth } = getOffset(actionEl);
  161 + if (moveX < offset) {
  162 + if (!props.isSlot) {
  163 + resume();
  164 + } else {
  165 + setTimeout(() => {
  166 + if (!props.value) {
  167 + resume();
  168 + } else {
  169 + const contentEl = unref(contentElRef);
  170 + if (contentEl) {
  171 + contentEl.style.width = `${parseInt(barEl.style.width)}px`;
  172 + }
170 173 }
171   - }
172   - }, 0);
  174 + }, 0);
  175 + }
  176 + } else {
  177 + actionEl.style.left = `${widthNum - actionWidth}px`;
  178 + barEl.style.width = `${widthNum - actionWidth / 2}px`;
  179 + checkPass();
173 180 }
174   - } else {
175   - actionEl.style.left = `${widthNum - actionWidth}px`;
176   - barEl.style.width = `${widthNum - actionWidth / 2}px`;
177   - checkPass();
  181 + state.isMoving = false;
178 182 }
179   - state.isMoving = false;
180 183 }
181   - }
182 184  
183   - function checkPass() {
184   - if (props.isSlot) {
185   - resume();
186   - return;
  185 + function checkPass() {
  186 + if (props.isSlot) {
  187 + resume();
  188 + return;
  189 + }
  190 + state.endTime = new Date().getTime();
  191 + state.isPassing = true;
  192 + state.isMoving = false;
187 193 }
188   - state.endTime = new Date().getTime();
189   - state.isPassing = true;
190   - state.isMoving = false;
191   - }
192 194  
193   - function resume() {
194   - state.isMoving = false;
195   - state.isPassing = false;
196   - state.moveDistance = 0;
197   - state.toLeft = false;
198   - state.startTime = 0;
199   - state.endTime = 0;
200   - const actionEl = unref(actionElRef);
201   - const barEl = unref(barElRef);
202   - const contentEl = unref(contentElRef);
203   - if (!actionEl || !barEl || !contentEl) return;
204   - state.toLeft = true;
205   - useTimeoutFn(() => {
  195 + function resume() {
  196 + state.isMoving = false;
  197 + state.isPassing = false;
  198 + state.moveDistance = 0;
206 199 state.toLeft = false;
207   - actionEl.style.left = '0';
208   - barEl.style.width = '0';
209   - // The time is consistent with the animation time
210   - }, 300);
211   - contentEl.style.width = unref(getContentStyleRef).width;
212   - }
  200 + state.startTime = 0;
  201 + state.endTime = 0;
  202 + const actionEl = unref(actionElRef);
  203 + const barEl = unref(barElRef);
  204 + const contentEl = unref(contentElRef);
  205 + if (!actionEl || !barEl || !contentEl) return;
  206 + state.toLeft = true;
  207 + useTimeoutFn(() => {
  208 + state.toLeft = false;
  209 + actionEl.style.left = '0';
  210 + barEl.style.width = '0';
  211 + // The time is consistent with the animation time
  212 + }, 300);
  213 + contentEl.style.width = unref(getContentStyleRef).width;
  214 + }
213 215  
214   - useExpose<DragVerifyActionType>({
215   - resume,
216   - });
  216 + expose({
  217 + resume,
  218 + });
217 219  
218   - return () => {
219   - const renderBar = () => {
220   - const cls = [`darg-verify-bar`];
221   - if (state.toLeft) {
222   - cls.push('to-left');
223   - }
224   - return <div class={cls} ref={barElRef} style={unref(getBarStyleRef)} />;
225   - };
  220 + return () => {
  221 + const renderBar = () => {
  222 + const cls = [`darg-verify-bar`];
  223 + if (state.toLeft) {
  224 + cls.push('to-left');
  225 + }
  226 + return <div class={cls} ref={barElRef} style={unref(getBarStyleRef)} />;
  227 + };
226 228  
227   - const renderContent = () => {
228   - const cls = [`darg-verify-content`];
229   - const { isPassing } = state;
230   - const { text, successText } = props;
  229 + const renderContent = () => {
  230 + const cls = [`darg-verify-content`];
  231 + const { isPassing } = state;
  232 + const { text, successText } = props;
231 233  
232   - isPassing && cls.push('success');
  234 + isPassing && cls.push('success');
233 235  
234   - return (
235   - <div class={cls} ref={contentElRef} style={unref(getContentStyleRef)}>
236   - {getSlot(slots, 'text', isPassing) || (isPassing ? successText : text)}
237   - </div>
238   - );
239   - };
  236 + return (
  237 + <div class={cls} ref={contentElRef} style={unref(getContentStyleRef)}>
  238 + {getSlot(slots, 'text', isPassing) || (isPassing ? successText : text)}
  239 + </div>
  240 + );
  241 + };
  242 +
  243 + const renderAction = () => {
  244 + const cls = [`darg-verify-action`];
  245 + const { toLeft, isPassing } = state;
  246 + if (toLeft) {
  247 + cls.push('to-left');
  248 + }
  249 + return (
  250 + <div
  251 + class={cls}
  252 + onMousedown={handleDragStart}
  253 + onTouchstart={handleDragStart}
  254 + style={unref(getActionStyleRef)}
  255 + ref={actionElRef}
  256 + >
  257 + {getSlot(slots, 'actionIcon', isPassing) ||
  258 + (isPassing ? (
  259 + <CheckOutlined class={`darg-verify-action__icon`} />
  260 + ) : (
  261 + <DoubleRightOutlined class={`darg-verify-action__icon`} />
  262 + ))}
  263 + </div>
  264 + );
  265 + };
240 266  
241   - const renderAction = () => {
242   - const cls = [`darg-verify-action`];
243   - const { toLeft, isPassing } = state;
244   - if (toLeft) {
245   - cls.push('to-left');
246   - }
247 267 return (
248 268 <div
249   - class={cls}
250   - onMousedown={handleDragStart}
251   - onTouchstart={handleDragStart}
252   - style={unref(getActionStyleRef)}
253   - ref={actionElRef}
  269 + class="darg-verify"
  270 + ref={wrapElRef}
  271 + style={unref(getWrapStyleRef)}
  272 + onMousemove={handleDragMoving}
  273 + onTouchmove={handleDragMoving}
  274 + onMouseleave={handleDragOver}
  275 + onMouseup={handleDragOver}
  276 + onTouchend={handleDragOver}
254 277 >
255   - {getSlot(slots, 'actionIcon', isPassing) ||
256   - (isPassing ? (
257   - <CheckOutlined class={`darg-verify-action__icon`} />
258   - ) : (
259   - <DoubleRightOutlined class={`darg-verify-action__icon`} />
260   - ))}
  278 + {renderBar()}
  279 + {renderContent()}
  280 + {renderAction()}
261 281 </div>
262 282 );
263 283 };
  284 + },
  285 + });
  286 +</script>
  287 +<style lang="less">
  288 + @radius: 4px;
  289 +
  290 + .darg-verify {
  291 + position: relative;
  292 + overflow: hidden;
  293 + text-align: center;
  294 + background-color: rgb(238, 238, 238);
  295 + border: 1px solid #ddd;
  296 + border-radius: @radius;
264 297  
265   - return (
266   - <div
267   - class="darg-verify"
268   - ref={wrapElRef}
269   - style={unref(getWrapStyleRef)}
270   - onMousemove={handleDragMoving}
271   - onTouchmove={handleDragMoving}
272   - onMouseleave={handleDragOver}
273   - onMouseup={handleDragOver}
274   - onTouchend={handleDragOver}
275   - >
276   - {renderBar()}
277   - {renderContent()}
278   - {renderAction()}
279   - </div>
  298 + &-bar {
  299 + position: absolute;
  300 + width: 0;
  301 + height: 36px;
  302 + background-color: @success-color;
  303 + border-radius: @radius;
  304 +
  305 + &.to-left {
  306 + width: 0 !important;
  307 + transition: width 0.3s;
  308 + }
  309 + }
  310 +
  311 + &-content {
  312 + position: absolute;
  313 + top: 0;
  314 + font-size: 12px;
  315 + -webkit-text-size-adjust: none;
  316 + background-color: -webkit-gradient(
  317 + linear,
  318 + left top,
  319 + right top,
  320 + color-stop(0, #333),
  321 + color-stop(0.4, #333),
  322 + color-stop(0.5, #fff),
  323 + color-stop(0.6, #333),
  324 + color-stop(1, #333)
280 325 );
281   - };
282   - },
283   -});
  326 + animation: slidetounlock 3s infinite;
  327 + -webkit-background-clip: text;
  328 + -moz-user-select: none;
  329 + -webkit-user-select: none;
  330 + -o-user-select: none;
  331 + -ms-user-select: none;
  332 + user-select: none;
  333 + -webkit-text-fill-color: transparent;
  334 +
  335 + &.success {
  336 + -webkit-text-fill-color: @white;
  337 + }
  338 +
  339 + & > * {
  340 + -webkit-text-fill-color: #333;
  341 + }
  342 + }
  343 +
  344 + &-action {
  345 + position: absolute;
  346 + top: 0;
  347 + left: 0;
  348 + display: flex;
  349 + cursor: move;
  350 + background-color: @white;
  351 + border-radius: @radius;
  352 + justify-content: center;
  353 + align-items: center;
  354 +
  355 + &__icon {
  356 + cursor: inherit;
  357 + }
  358 +
  359 + &.to-left {
  360 + left: 0 !important;
  361 + transition: left 0.3s;
  362 + }
  363 + }
  364 + }
  365 +
  366 + @-webkit-keyframes slidetounlock {
  367 + 0% {
  368 + background-position: -120px 0;
  369 + }
  370 +
  371 + 100% {
  372 + background-position: 120px 0;
  373 + }
  374 + }
  375 +</style>
... ...
src/components/Verify/src/ImgRotate.less deleted 100644 → 0
1   -.ir-dv {
2   - position: relative;
3   - display: flex;
4   - flex-direction: column;
5   - align-items: center;
6   -
7   - &-img__wrap {
8   - position: relative;
9   - overflow: hidden;
10   - border-radius: 50%;
11   -
12   - img {
13   - width: 100%;
14   - border-radius: 50%;
15   -
16   - &.to-origin {
17   - transition: transform 0.3s;
18   - }
19   - }
20   - }
21   -
22   - &-img__tip {
23   - position: absolute;
24   - bottom: 10px;
25   - left: 0;
26   - z-index: 1;
27   - display: block;
28   - width: 100%;
29   - height: 30px;
30   - font-size: 12px;
31   - line-height: 30px;
32   - color: @white;
33   - text-align: center;
34   -
35   - &.success {
36   - background-color: fade(@success-color, 60%);
37   - }
38   -
39   - &.error {
40   - background-color: fade(@error-color, 60%);
41   - }
42   -
43   - &.normal {
44   - background-color: rgba(0, 0, 0, 0.3);
45   - }
46   - }
47   -
48   - &-drag__bar {
49   - margin-top: 20px;
50   - }
51   -}
src/components/Verify/src/ImgRotate.tsx renamed to src/components/Verify/src/ImgRotate.vue
1   -import './ImgRotate.less';
2   -
3   -import type { MoveData, DragVerifyActionType } from './types';
4   -
5   -import { defineComponent, computed, unref, reactive, watch, ref, getCurrentInstance } from 'vue';
6   -import { useTimeoutFn } from '/@/hooks/core/useTimeout';
7   -
8   -import BasicDragVerify from './DragVerify';
9   -
10   -import { hackCss } from '/@/utils/domUtils';
11   -
12   -import { rotateProps } from './props';
13   -import { useI18n } from '/@/hooks/web/useI18n';
14   -
15   -export default defineComponent({
16   - name: 'ImgRotateDargVerify',
17   - inheritAttrs: false,
18   - props: rotateProps,
19   - emits: ['success', 'change', 'update:value'],
20   - setup(props, { emit, attrs }) {
21   - const basicRef = ref<Nullable<DragVerifyActionType>>(null);
22   - const state = reactive({
23   - showTip: false,
24   - isPassing: false,
25   - imgStyle: {},
26   - randomRotate: 0,
27   - currentRotate: 0,
28   - toOrigin: false,
29   - startTime: 0,
30   - endTime: 0,
31   - draged: false,
32   - });
33   - const { t } = useI18n();
34   -
35   - watch(
36   - () => state.isPassing,
37   - (isPassing) => {
38   - if (isPassing) {
39   - const { startTime, endTime } = state;
40   - const time = (endTime - startTime) / 1000;
41   - emit('success', { isPassing, time: time.toFixed(1) });
42   - emit('change', isPassing);
43   - emit('update:value', isPassing);
  1 +<script lang="tsx">
  2 + import type { MoveData, DragVerifyActionType } from './typing';
  3 + import { defineComponent, computed, unref, reactive, watch, ref, getCurrentInstance } from 'vue';
  4 + import { useTimeoutFn } from '/@/hooks/core/useTimeout';
  5 + import BasicDragVerify from './DragVerify.vue';
  6 + import { hackCss } from '/@/utils/domUtils';
  7 + import { rotateProps } from './props';
  8 + import { useI18n } from '/@/hooks/web/useI18n';
  9 +
  10 + export default defineComponent({
  11 + name: 'ImgRotateDargVerify',
  12 + inheritAttrs: false,
  13 + props: rotateProps,
  14 + emits: ['success', 'change', 'update:value'],
  15 + setup(props, { emit, attrs }) {
  16 + const basicRef = ref<Nullable<DragVerifyActionType>>(null);
  17 + const state = reactive({
  18 + showTip: false,
  19 + isPassing: false,
  20 + imgStyle: {},
  21 + randomRotate: 0,
  22 + currentRotate: 0,
  23 + toOrigin: false,
  24 + startTime: 0,
  25 + endTime: 0,
  26 + draged: false,
  27 + });
  28 + const { t } = useI18n();
  29 +
  30 + watch(
  31 + () => state.isPassing,
  32 + (isPassing) => {
  33 + if (isPassing) {
  34 + const { startTime, endTime } = state;
  35 + const time = (endTime - startTime) / 1000;
  36 + emit('success', { isPassing, time: time.toFixed(1) });
  37 + emit('change', isPassing);
  38 + emit('update:value', isPassing);
  39 + }
44 40 }
  41 + );
  42 +
  43 + const getImgWrapStyleRef = computed(() => {
  44 + const { imgWrapStyle, imgWidth } = props;
  45 + return {
  46 + width: `${imgWidth}px`,
  47 + height: `${imgWidth}px`,
  48 + ...imgWrapStyle,
  49 + };
  50 + });
  51 +
  52 + const getFactorRef = computed(() => {
  53 + const { minDegree, maxDegree } = props;
  54 + if (minDegree === maxDegree) {
  55 + return Math.floor(1 + Math.random() * 1) / 10 + 1;
  56 + }
  57 + return 1;
  58 + });
  59 + function handleStart() {
  60 + state.startTime = new Date().getTime();
45 61 }
46   - );
47   -
48   - const getImgWrapStyleRef = computed(() => {
49   - const { imgWrapStyle, imgWidth } = props;
50   - return {
51   - width: `${imgWidth}px`,
52   - height: `${imgWidth}px`,
53   - ...imgWrapStyle,
54   - };
55   - });
56 62  
57   - const getFactorRef = computed(() => {
58   - const { minDegree, maxDegree } = props;
59   - if (minDegree === maxDegree) {
60   - return Math.floor(1 + Math.random() * 1) / 10 + 1;
  63 + function handleDragBarMove(data: MoveData) {
  64 + state.draged = true;
  65 + const { imgWidth, height, maxDegree } = props;
  66 + const { moveX } = data;
  67 + const currentRotate = Math.ceil(
  68 + (moveX / (imgWidth! - parseInt(height as string))) * maxDegree! * unref(getFactorRef)
  69 + );
  70 + state.currentRotate = currentRotate;
  71 + state.imgStyle = hackCss('transform', `rotateZ(${state.randomRotate - currentRotate}deg)`);
61 72 }
62   - return 1;
63   - });
64   - function handleStart() {
65   - state.startTime = new Date().getTime();
66   - }
67 73  
68   - function handleDragBarMove(data: MoveData) {
69   - state.draged = true;
70   - const { imgWidth, height, maxDegree } = props;
71   - const { moveX } = data;
72   - const currentRotate = Math.ceil(
73   - (moveX / (imgWidth! - parseInt(height as string))) * maxDegree! * unref(getFactorRef)
74   - );
75   - state.currentRotate = currentRotate;
76   - state.imgStyle = hackCss('transform', `rotateZ(${state.randomRotate - currentRotate}deg)`);
77   - }
  74 + function handleImgOnLoad() {
  75 + const { minDegree, maxDegree } = props;
  76 + const ranRotate = Math.floor(minDegree! + Math.random() * (maxDegree! - minDegree!)); // 生成随机角度
  77 + state.randomRotate = ranRotate;
  78 + state.imgStyle = hackCss('transform', `rotateZ(${ranRotate}deg)`);
  79 + }
78 80  
79   - function handleImgOnLoad() {
80   - const { minDegree, maxDegree } = props;
81   - const ranRotate = Math.floor(minDegree! + Math.random() * (maxDegree! - minDegree!)); // 生成随机角度
82   - state.randomRotate = ranRotate;
83   - state.imgStyle = hackCss('transform', `rotateZ(${ranRotate}deg)`);
84   - }
  81 + function handleDragEnd() {
  82 + const { randomRotate, currentRotate } = state;
  83 + const { diffDegree } = props;
  84 +
  85 + if (Math.abs(randomRotate - currentRotate) >= (diffDegree || 20)) {
  86 + state.imgStyle = hackCss('transform', `rotateZ(${randomRotate}deg)`);
  87 + state.toOrigin = true;
  88 + useTimeoutFn(() => {
  89 + state.toOrigin = false;
  90 + state.showTip = true;
  91 + // 时间与动画时间保持一致
  92 + }, 300);
  93 + } else {
  94 + checkPass();
  95 + }
  96 + state.showTip = true;
  97 + }
  98 + function checkPass() {
  99 + state.isPassing = true;
  100 + state.endTime = new Date().getTime();
  101 + }
85 102  
86   - function handleDragEnd() {
87   - const { randomRotate, currentRotate } = state;
88   - const { diffDegree } = props;
89   -
90   - if (Math.abs(randomRotate - currentRotate) >= (diffDegree || 20)) {
91   - state.imgStyle = hackCss('transform', `rotateZ(${randomRotate}deg)`);
92   - state.toOrigin = true;
93   - useTimeoutFn(() => {
94   - state.toOrigin = false;
95   - state.showTip = true;
96   - // 时间与动画时间保持一致
97   - }, 300);
98   - } else {
99   - checkPass();
  103 + function resume() {
  104 + state.showTip = false;
  105 + const basicEl = unref(basicRef);
  106 + if (!basicEl) {
  107 + return;
  108 + }
  109 + state.isPassing = false;
  110 +
  111 + basicEl.resume();
  112 + handleImgOnLoad();
  113 + }
  114 +
  115 + const instance = getCurrentInstance() as any;
  116 + if (instance) {
  117 + instance.resume = resume;
  118 + }
  119 + // handleImgOnLoad();
  120 + return () => {
  121 + const { src } = props;
  122 + const { toOrigin, isPassing, startTime, endTime } = state;
  123 + const imgCls: string[] = [];
  124 + if (toOrigin) {
  125 + imgCls.push('to-origin');
  126 + }
  127 + const time = (endTime - startTime) / 1000;
  128 +
  129 + return (
  130 + <div class="ir-dv">
  131 + <div class={`ir-dv-img__wrap`} style={unref(getImgWrapStyleRef)}>
  132 + <img
  133 + src={src}
  134 + onLoad={handleImgOnLoad}
  135 + width={parseInt(props.width as string)}
  136 + class={imgCls}
  137 + style={state.imgStyle}
  138 + onClick={() => {
  139 + resume();
  140 + }}
  141 + />
  142 + {state.showTip && (
  143 + <span class={[`ir-dv-img__tip`, state.isPassing ? 'success' : 'error']}>
  144 + {state.isPassing
  145 + ? t('component.verify.time', { time: time.toFixed(1) })
  146 + : t('component.verify.error')}
  147 + </span>
  148 + )}
  149 + {!state.showTip && !state.draged && (
  150 + <span class={[`ir-dv-img__tip`, 'normal']}>{t('component.verify.redoTip')}</span>
  151 + )}
  152 + </div>
  153 + <BasicDragVerify
  154 + class={`ir-dv-drag__bar`}
  155 + onMove={handleDragBarMove}
  156 + onEnd={handleDragEnd}
  157 + onStart={handleStart}
  158 + ref={basicRef}
  159 + {...{ ...attrs, ...props }}
  160 + value={isPassing}
  161 + isSlot={true}
  162 + />
  163 + </div>
  164 + );
  165 + };
  166 + },
  167 + });
  168 +</script>
  169 +<style lang="less">
  170 + .ir-dv {
  171 + position: relative;
  172 + display: flex;
  173 + flex-direction: column;
  174 + align-items: center;
  175 +
  176 + &-img__wrap {
  177 + position: relative;
  178 + overflow: hidden;
  179 + border-radius: 50%;
  180 +
  181 + img {
  182 + width: 100%;
  183 + border-radius: 50%;
  184 +
  185 + &.to-origin {
  186 + transition: transform 0.3s;
  187 + }
100 188 }
101   - state.showTip = true;
102   - }
103   - function checkPass() {
104   - state.isPassing = true;
105   - state.endTime = new Date().getTime();
106 189 }
107 190  
108   - function resume() {
109   - state.showTip = false;
110   - const basicEl = unref(basicRef);
111   - if (!basicEl) {
112   - return;
  191 + &-img__tip {
  192 + position: absolute;
  193 + bottom: 10px;
  194 + left: 0;
  195 + z-index: 1;
  196 + display: block;
  197 + width: 100%;
  198 + height: 30px;
  199 + font-size: 12px;
  200 + line-height: 30px;
  201 + color: @white;
  202 + text-align: center;
  203 +
  204 + &.success {
  205 + background-color: fade(@success-color, 60%);
113 206 }
114   - state.isPassing = false;
115 207  
116   - basicEl.resume();
117   - handleImgOnLoad();
  208 + &.error {
  209 + background-color: fade(@error-color, 60%);
  210 + }
  211 +
  212 + &.normal {
  213 + background-color: rgba(0, 0, 0, 0.3);
  214 + }
118 215 }
119 216  
120   - const instance = getCurrentInstance() as any;
121   - if (instance) {
122   - instance.resume = resume;
  217 + &-drag__bar {
  218 + margin-top: 20px;
123 219 }
124   - // handleImgOnLoad();
125   - return () => {
126   - const { src } = props;
127   - const { toOrigin, isPassing, startTime, endTime } = state;
128   - const imgCls: string[] = [];
129   - if (toOrigin) {
130   - imgCls.push('to-origin');
131   - }
132   - const time = (endTime - startTime) / 1000;
133   -
134   - return (
135   - <div class="ir-dv">
136   - <div class={`ir-dv-img__wrap`} style={unref(getImgWrapStyleRef)}>
137   - <img
138   - src={src}
139   - onLoad={handleImgOnLoad}
140   - width={parseInt(props.width as string)}
141   - class={imgCls}
142   - style={state.imgStyle}
143   - onClick={() => {
144   - resume();
145   - }}
146   - />
147   - {state.showTip && (
148   - <span class={[`ir-dv-img__tip`, state.isPassing ? 'success' : 'error']}>
149   - {state.isPassing
150   - ? t('component.verify.time', { time: time.toFixed(1) })
151   - : t('component.verify.error')}
152   - </span>
153   - )}
154   - {!state.showTip && !state.draged && (
155   - <span class={[`ir-dv-img__tip`, 'normal']}>{t('component.verify.redoTip')}</span>
156   - )}
157   - </div>
158   - <BasicDragVerify
159   - class={`ir-dv-drag__bar`}
160   - onMove={handleDragBarMove}
161   - onEnd={handleDragEnd}
162   - onStart={handleStart}
163   - ref={basicRef}
164   - {...{ ...attrs, ...props }}
165   - value={isPassing}
166   - isSlot={true}
167   - />
168   - </div>
169   - );
170   - };
171   - },
172   -});
  220 + }
  221 +</style>
... ...
src/components/Verify/src/types.ts renamed to src/components/Verify/src/typing.ts
src/hooks/core/useExpose.ts deleted 100644 → 0
1   -import { getCurrentInstance } from 'vue';
2   -
3   -// expose public api
4   -export function useExpose<T>(apis: T) {
5   - const instance = getCurrentInstance();
6   - if (instance) {
7   - Object.assign(instance.proxy, apis);
8   - }
9   -}