Commit e034d1bacc5501a83188d20129951422bc127e3b

Authored by vben
1 parent 144fde8a

perf: remove optional chain

CHANGELOG.zh_CN.md
1 1 ## Wip
2 2  
  3 +### ✨ Features
  4 +
  5 +- 面包屑支持显示图标
  6 +- 新增 tinymce 富文本组件
  7 +
  8 +### 🎫 Chores
  9 +
  10 +- 删除代码内的可选链语法
  11 +
3 12 ### 🐛 Bug Fixes
4 13  
5 14 - 修复抽屉组件自动高度及显示 footer 显示问题
6 15 - 修复表单查询后重置回默认值
  16 +- 修复菜单没有子节点时显示折叠的问题
  17 +- 修复面包屑显示样式问题
  18 +- 修复 modal 在 destroyOnClose=true 时多次打开拖拽失效
7 19  
8 20 # 2.0.0-rc.4 (2020-10-21)
9 21  
... ...
src/components/Authority/index.ts 0 → 100644
  1 +import Authority from './src/index.vue';
  2 +export default Authority;
... ...
src/components/Authority/index.tsx renamed to src/components/Authority/src/index.vue
1   -import { defineComponent, PropType, computed, unref } from 'vue';
  1 +<script lang="ts">
  2 + import { defineComponent, PropType, computed, unref } from 'vue';
2 3  
3   -import { PermissionModeEnum } from '/@/enums/appEnum';
4   -import { RoleEnum } from '/@/enums/roleEnum';
5   -import { usePermission } from '/@/hooks/web/usePermission';
6   -import { appStore } from '/@/store/modules/app';
7   -import { getSlot } from '/@/utils/helper/tsxHelper';
  4 + import { PermissionModeEnum } from '/@/enums/appEnum';
  5 + import { RoleEnum } from '/@/enums/roleEnum';
  6 + import { usePermission } from '/@/hooks/web/usePermission';
  7 + import { appStore } from '/@/store/modules/app';
  8 + import { getSlot } from '/@/utils/helper/tsxHelper';
8 9  
9   -export default defineComponent({
10   - name: 'Authority',
11   - props: {
12   - // 指定角色可见
13   - value: {
14   - type: [Number, Array, String] as PropType<RoleEnum | RoleEnum[]>,
15   - default: '',
  10 + export default defineComponent({
  11 + name: 'Authority',
  12 + props: {
  13 + // 指定角色可见
  14 + value: {
  15 + type: [Number, Array, String] as PropType<RoleEnum | RoleEnum[]>,
  16 + default: '',
  17 + },
16 18 },
17   - },
18   - setup(props, { slots }) {
19   - const getModeRef = computed(() => {
20   - return appStore.getProjectConfig.permissionMode;
21   - });
  19 + setup(props, { slots }) {
  20 + const getModeRef = computed(() => {
  21 + return appStore.getProjectConfig.permissionMode;
  22 + });
22 23  
23   - /**
24   - * 渲染角色按钮
25   - */
26   - function renderRoleAuth() {
27   - const { value } = props;
28   - if (!value) {
29   - return getSlot(slots);
  24 + /**
  25 + * 渲染角色按钮
  26 + */
  27 + function renderRoleAuth() {
  28 + const { value } = props;
  29 + if (!value) {
  30 + return getSlot(slots);
  31 + }
  32 + const { hasPermission } = usePermission();
  33 + return hasPermission(value) ? getSlot(slots) : null;
30 34 }
31   - const { hasPermission } = usePermission();
32   - return hasPermission(value) ? getSlot(slots) : null;
33   - }
34 35  
35   - /**
36   - * 渲染编码按钮
37   - * 这里只判断是否包含,具体实现可以根据项目自行写逻辑
38   - */
39   - function renderCodeAuth() {
40   - const { value } = props;
41   - if (!value) {
42   - return getSlot(slots);
  36 + /**
  37 + * 渲染编码按钮
  38 + * 这里只判断是否包含,具体实现可以根据项目自行写逻辑
  39 + */
  40 + function renderCodeAuth() {
  41 + const { value } = props;
  42 + if (!value) {
  43 + return getSlot(slots);
  44 + }
  45 + const { hasPermission } = usePermission();
  46 + return hasPermission(value) ? getSlot(slots) : null;
43 47 }
44   - const { hasPermission } = usePermission();
45   - return hasPermission(value) ? getSlot(slots) : null;
46   - }
47 48  
48   - return () => {
49   - const mode = unref(getModeRef);
50   - // 基于角色渲染
51   - if (mode === PermissionModeEnum.ROLE) {
52   - return renderRoleAuth();
53   - }
54   - // 基于后台编码渲染
55   - if (mode === PermissionModeEnum.BACK) {
56   - return renderCodeAuth();
57   - }
58   - return getSlot(slots);
59   - };
60   - },
61   -});
  49 + return () => {
  50 + const mode = unref(getModeRef);
  51 + // 基于角色渲染
  52 + if (mode === PermissionModeEnum.ROLE) {
  53 + return renderRoleAuth();
  54 + }
  55 +
  56 + // 基于后台编码渲染
  57 + if (mode === PermissionModeEnum.BACK) {
  58 + return renderCodeAuth();
  59 + }
  60 +
  61 + return getSlot(slots);
  62 + };
  63 + },
  64 + });
  65 +</script>
... ...
src/components/Basic/index.ts
1 1 export { default as BasicArrow } from './src/BasicArrow.vue';
2   -export { default as BasicHelp } from './src/BasicHelp';
  2 +export { default as BasicHelp } from './src/BasicHelp.vue';
3 3 export { default as BasicTitle } from './src/BasicTitle.vue';
... ...
src/components/Basic/src/BasicHelp.less deleted 100644 → 0
1   -@import (reference) '../../../design/index.less';
2   -
3   -.base-help {
4   - display: inline-block;
5   - margin-left: 6px;
6   - font-size: 14px;
7   - color: @text-color-help-dark;
8   - cursor: pointer;
9   -
10   - &:hover {
11   - color: @primary-color;
12   - }
13   -
14   - &__wrap {
15   - p {
16   - margin-bottom: 0;
17   - }
18   - }
19   -}
src/components/Basic/src/BasicHelp.tsx renamed to src/components/Basic/src/BasicHelp.vue
1   -import type { PropType } from 'vue';
  1 +<script lang="ts">
  2 + import type { PropType } from 'vue';
2 3  
3   -import { Tooltip } from 'ant-design-vue';
4   -import { InfoCircleOutlined } from '@ant-design/icons-vue';
5   -import { defineComponent, computed, unref } from 'vue';
  4 + import { Tooltip } from 'ant-design-vue';
  5 + import { InfoCircleOutlined } from '@ant-design/icons-vue';
  6 + import { defineComponent, computed, unref, h } from 'vue';
6 7  
7   -import { getPopupContainer } from '/@/utils';
  8 + import { getPopupContainer } from '/@/utils';
8 9  
9   -import { isString, isArray } from '/@/utils/is';
10   -import { getSlot } from '/@/utils/helper/tsxHelper';
11   -import './BasicHelp.less';
12   -export default defineComponent({
13   - name: 'BaseHelp',
14   - props: {
15   - // max-width
16   - maxWidth: {
17   - type: String as PropType<string>,
18   - default: '600px',
  10 + import { isString, isArray } from '/@/utils/is';
  11 + import { getSlot } from '/@/utils/helper/tsxHelper';
  12 + export default defineComponent({
  13 + name: 'BaseHelp',
  14 + components: { Tooltip },
  15 + props: {
  16 + // max-width
  17 + maxWidth: {
  18 + type: String as PropType<string>,
  19 + default: '600px',
  20 + },
  21 + // Whether to display the serial number
  22 + showIndex: {
  23 + type: Boolean as PropType<boolean>,
  24 + default: false,
  25 + },
  26 + // Text list
  27 + text: {
  28 + type: [Array, String] as PropType<string[] | string>,
  29 + },
  30 + // color
  31 + color: {
  32 + type: String as PropType<string>,
  33 + default: '#ffffff',
  34 + },
  35 + fontSize: {
  36 + type: String as PropType<string>,
  37 + default: '14px',
  38 + },
  39 + absolute: {
  40 + type: Boolean as PropType<boolean>,
  41 + default: false,
  42 + },
  43 + // 定位
  44 + position: {
  45 + type: [Object] as PropType<any>,
  46 + default: () => ({
  47 + position: 'absolute',
  48 + left: 0,
  49 + bottom: 0,
  50 + }),
  51 + },
19 52 },
20   - // Whether to display the serial number
21   - showIndex: {
22   - type: Boolean as PropType<boolean>,
23   - default: false,
24   - },
25   - // Text list
26   - text: {
27   - type: [Array, String] as PropType<string[] | string>,
28   - },
29   - // color
30   - color: {
31   - type: String as PropType<string>,
32   - default: '#ffffff',
33   - },
34   - fontSize: {
35   - type: String as PropType<string>,
36   - default: '14px',
37   - },
38   - absolute: {
39   - type: Boolean as PropType<boolean>,
40   - default: false,
41   - },
42   - // 定位
43   - position: {
44   - type: [Object] as PropType<any>,
45   - default: () => ({
46   - position: 'absolute',
47   - left: 0,
48   - bottom: 0,
49   - }),
50   - },
51   - },
52   - setup(props, { slots }) {
53   - const getOverlayStyleRef = computed(() => {
54   - return {
55   - maxWidth: props.maxWidth,
  53 + setup(props, { slots }) {
  54 + const getOverlayStyleRef = computed(() => {
  55 + return {
  56 + maxWidth: props.maxWidth,
  57 + };
  58 + });
  59 + const getWrapStyleRef = computed(() => {
  60 + return {
  61 + color: props.color,
  62 + fontSize: props.fontSize,
  63 + };
  64 + });
  65 + const getMainStyleRef = computed(() => {
  66 + return props.absolute ? props.position : {};
  67 + });
  68 +
  69 + /**
  70 + * @description: 渲染内容
  71 + */
  72 + const renderTitle = () => {
  73 + const list = props.text;
  74 + if (isString(list)) {
  75 + return h('p', list);
  76 + }
  77 + if (isArray(list)) {
  78 + return list.map((item, index) => {
  79 + return h('p', { key: item }, [props.showIndex ? `${index + 1}. ` : '', item]);
  80 + });
  81 + }
  82 + return null;
56 83 };
57   - });
58   - const getWrapStyleRef = computed(() => {
59   - return {
60   - color: props.color,
61   - fontSize: props.fontSize,
  84 + return () => {
  85 + return h(
  86 + Tooltip,
  87 + {
  88 + title: h(
  89 + 'div',
  90 + {
  91 + style: unref(getWrapStyleRef),
  92 + },
  93 + [renderTitle()]
  94 + ) as any,
  95 + overlayClassName: 'base-help__wrap',
  96 + autoAdjustOverflow: true,
  97 + overlayStyle: unref(getOverlayStyleRef),
  98 + placement: 'right',
  99 + getPopupContainer: () => getPopupContainer(),
  100 + },
  101 + {
  102 + default: () =>
  103 + h(
  104 + 'span',
  105 + {
  106 + class: 'base-help',
  107 + style: unref(getMainStyleRef),
  108 + },
  109 + getSlot(slots) || h(InfoCircleOutlined)
  110 + ),
  111 + }
  112 + );
62 113 };
63   - });
64   - const getMainStyleRef = computed(() => {
65   - return props.absolute ? props.position : {};
66   - });
  114 + },
  115 + });
  116 +</script>
  117 +<style lang="less">
  118 + @import (reference) '../../../design/index.less';
67 119  
68   - /**
69   - * @description: 渲染内容
70   - */
71   - const renderTitle = () => {
72   - const list = props.text;
73   - if (isString(list)) {
74   - return <p>{list}</p>;
75   - }
76   - if (isArray(list)) {
77   - return list.map((item, index) => {
78   - return (
79   - <p key={item}>
80   - {props.showIndex ? `${index + 1}. ` : ''}
81   - {item}
82   - </p>
83   - );
84   - });
  120 + .base-help {
  121 + display: inline-block;
  122 + margin-left: 6px;
  123 + font-size: 14px;
  124 + color: @text-color-help-dark;
  125 + cursor: pointer;
  126 +
  127 + &:hover {
  128 + color: @primary-color;
  129 + }
  130 +
  131 + &__wrap {
  132 + p {
  133 + margin-bottom: 0;
85 134 }
86   - return null;
87   - };
88   - return () => (
89   - <Tooltip
90   - title={(<div style={unref(getWrapStyleRef)}>{renderTitle()}</div>) as any}
91   - placement="right"
92   - overlayStyle={unref(getOverlayStyleRef)}
93   - autoAdjustOverflow={true}
94   - overlayClassName="base-help__wrap"
95   - getPopupContainer={() => getPopupContainer()}
96   - >
97   - {{
98   - default: () => (
99   - <span class="base-help" style={unref(getMainStyleRef)}>
100   - {getSlot(slots) || <InfoCircleOutlined />}
101   - </span>
102   - ),
103   - }}
104   - </Tooltip>
105   - );
106   - },
107   -});
  135 + }
  136 + }
  137 +</style>
... ...
src/components/Button/types.ts deleted 100644 → 0
1   -import { VNodeChild } from 'vue';
2   -
3   -export interface BasicButtonProps {
4   - /**
5   - * can be set to primary ghost dashed danger(added in 2.7) or omitted (meaning default)
6   - * @default 'default'
7   - * @type string
8   - */
9   - type?: 'primary' | 'danger' | 'dashed' | 'ghost' | 'default';
10   -
11   - /**
12   - * set the original html type of button
13   - * @default 'button'
14   - * @type string
15   - */
16   - htmlType?: 'button' | 'submit' | 'reset' | 'menu';
17   -
18   - /**
19   - * set the icon of button
20   - * @type string
21   - */
22   - icon?: VNodeChild | JSX.Element;
23   -
24   - /**
25   - * can be set to circle or circle-outline or omitted
26   - * @type string
27   - */
28   - shape?: 'circle' | 'circle-outline';
29   -
30   - /**
31   - * can be set to small large or omitted
32   - * @default 'default'
33   - * @type string
34   - */
35   - size?: 'small' | 'large' | 'default';
36   -
37   - /**
38   - * set the loading status of button
39   - * @default false
40   - * @type boolean | { delay: number }
41   - */
42   - loading?: boolean | { delay: number };
43   -
44   - /**
45   - * disabled state of button
46   - * @default false
47   - * @type boolean
48   - */
49   - disabled?: boolean;
50   -
51   - /**
52   - * make background transparent and invert text and border colors, added in 2.7
53   - * @default false
54   - * @type boolean
55   - */
56   - ghost?: boolean;
57   -
58   - /**
59   - * option to fit button width to its parent width
60   - * @default false
61   - * @type boolean
62   - */
63   - block?: boolean;
64   -
65   - onClick?: (e?: Event) => void;
66   -}
src/components/Table/src/components/TableAction.tsx
... ... @@ -84,10 +84,11 @@ export default defineComponent({
84 84 const { dropDownActions = [], actions } = props;
85 85 return (
86 86 <div class={prefixCls}>
87   - {actions?.map((action, index) => {
88   - return renderPopConfirm(action, index);
89   - })}
90   - {dropDownActions?.length && (
  87 + {actions &&
  88 + actions.map((action, index) => {
  89 + return renderPopConfirm(action, index);
  90 + })}
  91 + {dropDownActions && dropDownActions.length && (
91 92 <Dropdown>
92 93 {{
93 94 default: dropdownDefaultSLot,
... ...
src/components/Table/src/components/renderEditableCell.tsx
... ... @@ -45,8 +45,8 @@ const EditableCell = defineComponent({
45 45 const isEditRef = ref(false);
46 46 const currentValueRef = ref<string | boolean>(props.value);
47 47  
48   - function handleChange(e: ChangeEvent | string | boolean) {
49   - if (Reflect.has((e as ChangeEvent)?.target, 'value')) {
  48 + function handleChange(e: any) {
  49 + if (e && e.target && Reflect.has(e.target, 'value')) {
50 50 currentValueRef.value = (e as ChangeEvent).target.value;
51 51 }
52 52 if (isString(e) || isBoolean(e)) {
... ... @@ -58,7 +58,7 @@ const EditableCell = defineComponent({
58 58 isEditRef.value = true;
59 59 nextTick(() => {
60 60 const el = unref(elRef);
61   - el?.focus();
  61 + el && el.focus();
62 62 });
63 63 }
64 64  
... ... @@ -84,7 +84,7 @@ const EditableCell = defineComponent({
84 84 function onClickOutside() {
85 85 const { component } = props;
86 86  
87   - if (component?.includes('Input')) {
  87 + if (component && component.includes('Input')) {
88 88 handleCancel();
89 89 }
90 90 }
... ...
src/components/Table/src/hooks/useDataSource.ts
... ... @@ -89,7 +89,7 @@ export function useDataSource(
89 89 pageParams = {};
90 90 } else {
91 91 const { current, pageSize } = unref(getPaginationRef) as PaginationProps;
92   - pageParams[pageField] = opt?.page || current;
  92 + pageParams[pageField] = (opt && opt.page) || current;
93 93 pageParams[sizeField] = pageSize;
94 94 }
95 95  
... ...
src/components/Tinymce/src/Editor.vue
... ... @@ -53,13 +53,12 @@
53 53 });
54 54  
55 55 const initOptions = computed(() => {
56   - const { height, menubar } = props;
  56 + const { height, options } = props;
57 57 return {
58 58 selector: `#${unref(tinymceId)}`,
59 59 height: height,
60 60 toolbar: toolbar,
61   - theme: 'silver',
62   - menubar: menubar,
  61 + menubar: 'file edit insert view format table',
63 62 plugins: plugins,
64 63 // 语言包
65 64 language_url: 'resource/tinymce/langs/zh_CN.js',
... ... @@ -70,6 +69,7 @@
70 69 advlist_bullet_styles: 'square',
71 70 advlist_number_styles: 'default',
72 71 object_resizing: false,
  72 + ...options,
73 73 setup: (editor: any) => {
74 74 editorRef.value = editor;
75 75 editor.on('init', (e: Event) => initSetup(e));
... ...
src/components/Tinymce/src/props.ts
1 1 import { PropType } from 'vue';
2 2  
3 3 export const basicProps = {
4   - menubar: {
5   - type: String as PropType<string>,
6   - default: 'file edit insert view format table',
  4 + options: {
  5 + type: Object as PropType<any>,
  6 + default: {},
7 7 },
8 8 value: {
9 9 type: String as PropType<string>,
... ...
src/views/demo/editor/tinymce/index.vue
1 1 <template>
2   - <div class="flex p-4">
3   - {{ value }}
  2 + <div class="p-4">
4 3 <Tinymce v-model="value" @change="handleChange" width="100%" />
5 4 </div>
6 5 </template>
... ... @@ -15,9 +14,6 @@
15 14 function handleChange(value: string) {
16 15 console.log(value);
17 16 }
18   - // setTimeout(() => {
19   - // value.value = '1233';
20   - // }, 5000);
21 17 return { handleChange, value };
22 18 },
23 19 });
... ...
vite.config.ts
... ... @@ -8,7 +8,6 @@ import {
8 8 // externals,
9 9 cdnConf,
10 10 } from './build/config/vite/cdn';
11   -
12 11 import { createProxy } from './build/config/vite/proxy';
13 12 import { createMockServer } from 'vite-plugin-mock';
14 13 import PurgeIcons from 'vite-plugin-purge-icons';
... ...