Commit 9bb751475dc212d4e2829468cf1a11502137071e

Authored by vben
1 parent 29461a85

perf: tsx use useExpose

CHANGELOG.zh_CN.md
@@ -13,6 +13,10 @@ @@ -13,6 +13,10 @@
13 - 打包代码拆分(试验) 13 - 打包代码拆分(试验)
14 - 提取上传地址到全局变量,打包可以动态配置 14 - 提取上传地址到全局变量,打包可以动态配置
15 15
  16 +### ✨ Refactor
  17 +
  18 +- tree 组件 ref 函数调用删除 `$`
  19 +
16 ### ⚡ Performance Improvements 20 ### ⚡ Performance Improvements
17 21
18 - 页面切换 loading 逻辑修改。对于已经加载过的页面不管有没有关闭,再次打开不会在显示 loading(已经打开过的页面再次打开速度比较快,可以不需要 loading,同理顶部进度条逻辑也一样),刷新后恢复。 22 - 页面切换 loading 逻辑修改。对于已经加载过的页面不管有没有关闭,再次打开不会在显示 loading(已经打开过的页面再次打开速度比较快,可以不需要 loading,同理顶部进度条逻辑也一样),刷新后恢复。
src/components/Container/src/ScrollContainer.vue
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 11
12 <script lang="ts"> 12 <script lang="ts">
13 import { defineComponent, ref, unref, nextTick } from 'vue'; 13 import { defineComponent, ref, unref, nextTick } from 'vue';
14 - import { Scrollbar } from '/@/components/Scrollbar'; 14 + import { Scrollbar, ScrollbarType } from '/@/components/Scrollbar';
15 15
16 import { useScrollTo } from '/@/hooks/event/useScrollTo'; 16 import { useScrollTo } from '/@/hooks/event/useScrollTo';
17 17
@@ -19,15 +19,17 @@ @@ -19,15 +19,17 @@
19 name: 'ScrollContainer', 19 name: 'ScrollContainer',
20 components: { Scrollbar }, 20 components: { Scrollbar },
21 setup() { 21 setup() {
22 - const scrollbarRef = ref<RefInstanceType<any>>(null); 22 + const scrollbarRef = ref<Nullable<ScrollbarType>>(null);
23 23
24 function scrollTo(to: number, duration = 500) { 24 function scrollTo(to: number, duration = 500) {
25 const scrollbar = unref(scrollbarRef); 25 const scrollbar = unref(scrollbarRef);
26 if (!scrollbar) return; 26 if (!scrollbar) return;
27 27
28 nextTick(() => { 28 nextTick(() => {
  29 + const wrap = unref(scrollbar.wrap);
  30 + if (!wrap) return;
29 const { start } = useScrollTo({ 31 const { start } = useScrollTo({
30 - el: unref(scrollbar.$.wrap), 32 + el: wrap,
31 to, 33 to,
32 duration, 34 duration,
33 }); 35 });
@@ -38,7 +40,7 @@ @@ -38,7 +40,7 @@
38 function getScrollWrap() { 40 function getScrollWrap() {
39 const scrollbar = unref(scrollbarRef); 41 const scrollbar = unref(scrollbarRef);
40 if (!scrollbar) return null; 42 if (!scrollbar) return null;
41 - return scrollbar.$.wrap; 43 + return scrollbar.wrap;
42 } 44 }
43 45
44 function scrollBottom() { 46 function scrollBottom() {
@@ -46,9 +48,11 @@ @@ -46,9 +48,11 @@
46 if (!scrollbar) return; 48 if (!scrollbar) return;
47 49
48 nextTick(() => { 50 nextTick(() => {
49 - const scrollHeight = scrollbar.$.wrap.scrollHeight as number; 51 + const wrap = unref(scrollbar.wrap);
  52 + if (!wrap) return;
  53 + const scrollHeight = wrap.scrollHeight as number;
50 const { start } = useScrollTo({ 54 const { start } = useScrollTo({
51 - el: unref(scrollbar.$.wrap), 55 + el: wrap,
52 to: scrollHeight, 56 to: scrollHeight,
53 }); 57 });
54 start(); 58 start();
src/components/Form/src/BasicForm.vue
@@ -31,17 +31,7 @@ @@ -31,17 +31,7 @@
31 import type { Ref, WatchStopHandle } from 'vue'; 31 import type { Ref, WatchStopHandle } from 'vue';
32 import type { ValidateFields } from 'ant-design-vue/lib/form/interface'; 32 import type { ValidateFields } from 'ant-design-vue/lib/form/interface';
33 33
34 - import {  
35 - defineComponent,  
36 - reactive,  
37 - ref,  
38 - computed,  
39 - unref,  
40 - toRef,  
41 - onMounted,  
42 - watch,  
43 - toRefs,  
44 - } from 'vue'; 34 + import { defineComponent, reactive, ref, computed, unref, onMounted, watch, toRefs } from 'vue';
45 import { Form, Row } from 'ant-design-vue'; 35 import { Form, Row } from 'ant-design-vue';
46 import FormItem from './FormItem'; 36 import FormItem from './FormItem';
47 import { basicProps } from './props'; 37 import { basicProps } from './props';
src/components/Scrollbar/index.ts
@@ -2,4 +2,10 @@ @@ -2,4 +2,10 @@
2 * copy from element-ui 2 * copy from element-ui
3 */ 3 */
4 4
5 -export { default as Scrollbar } from './src/Scrollbar'; 5 +import Scrollbar from './src/Scrollbar';
  6 +import { withInstall } from '../util';
  7 +
  8 +withInstall(Scrollbar);
  9 +
  10 +export { Scrollbar };
  11 +export type { ScrollbarType } from './src/types';
src/components/Scrollbar/src/Scrollbar.tsx
@@ -15,8 +15,9 @@ import { @@ -15,8 +15,9 @@ import {
15 onBeforeUnmount, 15 onBeforeUnmount,
16 } from 'vue'; 16 } from 'vue';
17 import { getSlot } from '/@/utils/helper/tsxHelper'; 17 import { getSlot } from '/@/utils/helper/tsxHelper';
18 -import { tryTsxEmit } from '/@/utils/helper/vueHelper';  
19 import './index.less'; 18 import './index.less';
  19 +import { useExpose } from '/@/hooks/core/useExpose';
  20 +import { ScrollbarType } from './types';
20 21
21 export default defineComponent({ 22 export default defineComponent({
22 name: 'Scrollbar', 23 name: 'Scrollbar',
@@ -65,10 +66,9 @@ export default defineComponent({ @@ -65,10 +66,9 @@ export default defineComponent({
65 } 66 }
66 67
67 onMounted(() => { 68 onMounted(() => {
68 - tryTsxEmit<any>((instance) => {  
69 - instance.wrap = unref(wrapElRef); 69 + useExpose<ScrollbarType>({
  70 + wrap: unref(wrapElRef),
70 }); 71 });
71 -  
72 const { native, noresize } = props; 72 const { native, noresize } = props;
73 const resizeEl = unref(resizeRef); 73 const resizeEl = unref(resizeRef);
74 const warpEl = unref(wrapElRef); 74 const warpEl = unref(wrapElRef);
src/components/Scrollbar/src/types.d.ts
@@ -12,3 +12,7 @@ export interface BarMap { @@ -12,3 +12,7 @@ export interface BarMap {
12 vertical: BarMapItem; 12 vertical: BarMapItem;
13 horizontal: BarMapItem; 13 horizontal: BarMapItem;
14 } 14 }
  15 +
  16 +export interface ScrollbarType {
  17 + wrap: ElRef;
  18 +}
src/components/Table/src/BasicTable.vue
@@ -69,6 +69,7 @@ @@ -69,6 +69,7 @@
69 import { basicProps } from './props'; 69 import { basicProps } from './props';
70 import { ROW_KEY } from './const'; 70 import { ROW_KEY } from './const';
71 import './style/index.less'; 71 import './style/index.less';
  72 + import { useExpose } from '/@/hooks/core/useExpose';
72 export default defineComponent({ 73 export default defineComponent({
73 props: basicProps, 74 props: basicProps,
74 components: { Table, BasicForm }, 75 components: { Table, BasicForm },
@@ -309,6 +310,8 @@ @@ -309,6 +310,8 @@
309 wrapRef, 310 wrapRef,
310 }); 311 });
311 312
  313 + useExpose<TableActionType>(tableAction);
  314 +
312 emit('register', tableAction); 315 emit('register', tableAction);
313 return { 316 return {
314 tableElRef, 317 tableElRef,
@@ -322,7 +325,7 @@ @@ -322,7 +325,7 @@
322 getRowClassName, 325 getRowClassName,
323 wrapRef, 326 wrapRef,
324 tableAction, 327 tableAction,
325 - ...tableAction, 328 + redoHeight,
326 }; 329 };
327 }, 330 },
328 }); 331 });
src/components/Tree/src/BasicTree.tsx
@@ -11,10 +11,10 @@ import { useContextMenu, ContextMenuItem } from &#39;/@/hooks/web/useContextMenu&#39;; @@ -11,10 +11,10 @@ import { useContextMenu, ContextMenuItem } from &#39;/@/hooks/web/useContextMenu&#39;;
11 import { isFunction } from '/@/utils/is'; 11 import { isFunction } from '/@/utils/is';
12 import { omit } from 'lodash-es'; 12 import { omit } from 'lodash-es';
13 import { extendSlots } from '/@/utils/helper/tsxHelper'; 13 import { extendSlots } from '/@/utils/helper/tsxHelper';
14 -import { tryTsxEmit } from '/@/utils/helper/vueHelper';  
15 14
16 import { basicProps } from './props'; 15 import { basicProps } from './props';
17 import { useTree } from './useTree'; 16 import { useTree } from './useTree';
  17 +import { useExpose } from '/@/hooks/core/useExpose';
18 18
19 interface State { 19 interface State {
20 expandedKeys: Keys; 20 expandedKeys: Keys;
@@ -182,20 +182,21 @@ export default defineComponent({ @@ -182,20 +182,21 @@ export default defineComponent({
182 state.checkedKeys = props.checkedKeys; 182 state.checkedKeys = props.checkedKeys;
183 }); 183 });
184 184
185 - tryTsxEmit<TreeActionType>((currentInstance) => {  
186 - currentInstance.setExpandedKeys = setExpandedKeys;  
187 - currentInstance.getExpandedKeys = getExpandedKeys;  
188 - currentInstance.setSelectedKeys = setSelectedKeys;  
189 - currentInstance.getSelectedKeys = getSelectedKeys;  
190 - currentInstance.setCheckedKeys = setCheckedKeys;  
191 - currentInstance.getCheckedKeys = getCheckedKeys;  
192 - currentInstance.insertNodeByKey = insertNodeByKey;  
193 - currentInstance.deleteNodeByKey = deleteNodeByKey;  
194 - currentInstance.updateNodeByKey = updateNodeByKey;  
195 - currentInstance.filterByLevel = (level: number) => { 185 + useExpose<TreeActionType>({
  186 + setExpandedKeys,
  187 + getExpandedKeys,
  188 + setSelectedKeys,
  189 + getSelectedKeys,
  190 + setCheckedKeys,
  191 + getCheckedKeys,
  192 + insertNodeByKey,
  193 + deleteNodeByKey,
  194 + updateNodeByKey,
  195 + filterByLevel: (level: number) => {
196 state.expandedKeys = filterByLevel(level); 196 state.expandedKeys = filterByLevel(level);
197 - }; 197 + },
198 }); 198 });
  199 +
199 return () => { 200 return () => {
200 return ( 201 return (
201 <Tree {...unref(getBindValues)} class={prefixCls}> 202 <Tree {...unref(getBindValues)} class={prefixCls}>
src/components/Verify/src/DragVerify.tsx
@@ -5,8 +5,8 @@ import { basicProps } from &#39;./props&#39;; @@ -5,8 +5,8 @@ import { basicProps } from &#39;./props&#39;;
5 import { getSlot } from '/@/utils/helper/tsxHelper'; 5 import { getSlot } from '/@/utils/helper/tsxHelper';
6 import './DragVerify.less'; 6 import './DragVerify.less';
7 import { CheckOutlined, DoubleRightOutlined } from '@ant-design/icons-vue'; 7 import { CheckOutlined, DoubleRightOutlined } from '@ant-design/icons-vue';
8 -import { tryTsxEmit } from '/@/utils/helper/vueHelper';  
9 import type { DragVerifyActionType } from './types'; 8 import type { DragVerifyActionType } from './types';
  9 +import { useExpose } from '/@/hooks/core/useExpose';
10 export default defineComponent({ 10 export default defineComponent({
11 name: 'BaseDargVerify', 11 name: 'BaseDargVerify',
12 props: basicProps, 12 props: basicProps,
@@ -211,8 +211,8 @@ export default defineComponent({ @@ -211,8 +211,8 @@ export default defineComponent({
211 contentEl.style.width = unref(getContentStyleRef).width; 211 contentEl.style.width = unref(getContentStyleRef).width;
212 } 212 }
213 213
214 - tryTsxEmit<DragVerifyActionType>((instance) => {  
215 - instance.resume = resume; 214 + useExpose<DragVerifyActionType>({
  215 + resume,
216 }); 216 });
217 217
218 return () => { 218 return () => {
src/components/Verify/src/ImgRotate.tsx
@@ -18,7 +18,7 @@ export default defineComponent({ @@ -18,7 +18,7 @@ export default defineComponent({
18 props: rotateProps, 18 props: rotateProps,
19 emits: ['success', 'change', 'update:value'], 19 emits: ['success', 'change', 'update:value'],
20 setup(props, { emit, attrs }) { 20 setup(props, { emit, attrs }) {
21 - const basicRef = ref<RefInstanceType<DragVerifyActionType>>(null); 21 + const basicRef = ref<Nullable<DragVerifyActionType>>(null);
22 const state = reactive({ 22 const state = reactive({
23 showTip: false, 23 showTip: false,
24 isPassing: false, 24 isPassing: false,
@@ -113,7 +113,7 @@ export default defineComponent({ @@ -113,7 +113,7 @@ export default defineComponent({
113 } 113 }
114 state.isPassing = false; 114 state.isPassing = false;
115 115
116 - basicEl.$.resume(); 116 + basicEl.resume();
117 handleImgOnLoad(); 117 handleImgOnLoad();
118 } 118 }
119 119
src/hooks/core/useExpose.ts
1 import { getCurrentInstance } from 'vue'; 1 import { getCurrentInstance } from 'vue';
2 2
3 // expose public api 3 // expose public api
4 -export function useExpose(apis: Record<string, any>) { 4 +export function useExpose<T>(apis: T) {
5 const instance = getCurrentInstance(); 5 const instance = getCurrentInstance();
6 if (instance) { 6 if (instance) {
7 Object.assign(instance.proxy, apis); 7 Object.assign(instance.proxy, apis);
src/types/global.d.ts
@@ -19,10 +19,6 @@ declare type Dictionary&lt;T&gt; = Record&lt;string, T&gt;; @@ -19,10 +19,6 @@ declare type Dictionary&lt;T&gt; = Record&lt;string, T&gt;;
19 19
20 declare type Nullable<T> = T | null; 20 declare type Nullable<T> = T | null;
21 21
22 -declare type RefInstanceType<T> = {  
23 - $: T;  
24 -} | null;  
25 -  
26 declare type RefType<T> = T | null; 22 declare type RefType<T> = T | null;
27 23
28 declare type CustomizedHTMLElement<T> = HTMLElement & T; 24 declare type CustomizedHTMLElement<T> = HTMLElement & T;
src/views/demo/comp/verify/index.vue
@@ -59,22 +59,22 @@ @@ -59,22 +59,22 @@
59 components: { BasicDragVerify, BugOutlined, RightOutlined }, 59 components: { BasicDragVerify, BugOutlined, RightOutlined },
60 setup() { 60 setup() {
61 const { createMessage } = useMessage(); 61 const { createMessage } = useMessage();
62 - const el1 = ref<RefInstanceType<DragVerifyActionType>>(null);  
63 - const el2 = ref<RefInstanceType<DragVerifyActionType>>(null);  
64 - const el3 = ref<RefInstanceType<DragVerifyActionType>>(null);  
65 - const el4 = ref<RefInstanceType<DragVerifyActionType>>(null);  
66 - const el5 = ref<RefInstanceType<DragVerifyActionType>>(null); 62 + const el1 = ref<Nullable<DragVerifyActionType>>(null);
  63 + const el2 = ref<Nullable<DragVerifyActionType>>(null);
  64 + const el3 = ref<Nullable<DragVerifyActionType>>(null);
  65 + const el4 = ref<Nullable<DragVerifyActionType>>(null);
  66 + const el5 = ref<Nullable<DragVerifyActionType>>(null);
67 67
68 function handleSuccess(data: PassingData) { 68 function handleSuccess(data: PassingData) {
69 const { time } = data; 69 const { time } = data;
70 createMessage.success(`校验成功,耗时${time}秒`); 70 createMessage.success(`校验成功,耗时${time}秒`);
71 } 71 }
72 72
73 - function handleBtnClick(elRef: RefInstanceType<DragVerifyActionType>) { 73 + function handleBtnClick(elRef: Nullable<DragVerifyActionType>) {
74 if (!elRef) { 74 if (!elRef) {
75 return; 75 return;
76 } 76 }
77 - elRef.$.resume(); 77 + elRef.resume();
78 } 78 }
79 return { 79 return {
80 handleSuccess, 80 handleSuccess,
src/views/demo/tree/ActionTree.vue
@@ -32,14 +32,14 @@ @@ -32,14 +32,14 @@
32 export default defineComponent({ 32 export default defineComponent({
33 components: { BasicTree, CollapseContainer }, 33 components: { BasicTree, CollapseContainer },
34 setup() { 34 setup() {
35 - const treeRef = ref<RefInstanceType<TreeActionType>>(null); 35 + const treeRef = ref<Nullable<TreeActionType>>(null);
36 const { createMessage } = useMessage(); 36 const { createMessage } = useMessage();
37 function getTree() { 37 function getTree() {
38 const tree = unref(treeRef); 38 const tree = unref(treeRef);
39 if (!tree) { 39 if (!tree) {
40 throw new Error('tree is null!'); 40 throw new Error('tree is null!');
41 } 41 }
42 - return tree.$; 42 + return tree;
43 } 43 }
44 44
45 function handleLevel(level: number) { 45 function handleLevel(level: number) {