Commit e034d1bacc5501a83188d20129951422bc127e3b
1 parent
144fde8a
perf: remove optional chain
Showing
14 changed files
with
218 additions
and
259 deletions
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
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
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