├── .browserslistrc ├── .editorconfig ├── .env.npm ├── .eslintrc.js ├── .gitignore ├── .npmignore ├── README.md ├── babel.config.js ├── buildConfig ├── build.js └── npmBuild.js ├── docs ├── css │ ├── 146.3a49afba.css │ ├── 331.3a49afba.css │ ├── 545.15d37a70.css │ ├── 653.3a49afba.css │ ├── 824.4916a807.css │ ├── app.4ec54d1f.css │ └── chunk-vendors.c93aebbb.css ├── favicon.ico ├── img │ └── icons │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── android-chrome-maskable-192x192.png │ │ ├── android-chrome-maskable-512x512.png │ │ ├── apple-touch-icon-120x120.png │ │ ├── apple-touch-icon-152x152.png │ │ ├── apple-touch-icon-180x180.png │ │ ├── apple-touch-icon-60x60.png │ │ ├── apple-touch-icon-76x76.png │ │ ├── apple-touch-icon.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── msapplication-icon-144x144.png │ │ ├── mstile-150x150.png │ │ └── safari-pinned-tab.svg ├── index.html ├── js │ ├── 126.2a7793a1.js │ ├── 146.3cd1c469.js │ ├── 331.971e2d17.js │ ├── 545.61c4e24b.js │ ├── 653.82888ac1.js │ ├── 824.23fdc32b.js │ ├── app.488df1ba.js │ └── chunk-vendors.91dd5e1d.js ├── manifest.json ├── robots.txt ├── service-worker.js ├── static │ ├── apiDocs2 │ │ ├── .nojekyll │ │ ├── assets │ │ │ ├── highlight.css │ │ │ ├── icons.css │ │ │ ├── icons.png │ │ │ ├── icons@2x.png │ │ │ ├── main.js │ │ │ ├── search.js │ │ │ ├── style.css │ │ │ ├── widgets.png │ │ │ └── widgets@2x.png │ │ ├── index.html │ │ ├── interfaces │ │ │ ├── BsButtons.buttonFace.html │ │ │ ├── BsDialog.dialogFace.html │ │ │ ├── BsDialog_BsFormDialog.dialogFormFace.html │ │ │ ├── BsDialog_BsFormDialog.dialogFormShowConfigFace.html │ │ │ ├── BsDialog_BsListDialog.dialogListFace.html │ │ │ ├── BsDialog_BsListDialog.dialogListShowConfigFace.html │ │ │ ├── BsEditTable.editTableColumnsItemConfig.html │ │ │ ├── BsEditTable.editTableConfigFace.html │ │ │ ├── BsForm.cascaderProps.html │ │ │ ├── BsForm.checkboxProps.html │ │ │ ├── BsForm.collapseProps.html │ │ │ ├── BsForm.dateProps.html │ │ │ ├── BsForm.dateRangeProps.html │ │ │ ├── BsForm.editTableProps.html │ │ │ ├── BsForm.formConfig.html │ │ │ ├── BsForm.inputProps.html │ │ │ ├── BsForm.numberProps.html │ │ │ ├── BsForm.numberRangeProps.html │ │ │ ├── BsForm.passwordProps.html │ │ │ ├── BsForm.radioProps.html │ │ │ ├── BsForm.renderProps.html │ │ │ ├── BsForm.selectProps.html │ │ │ ├── BsForm.switchProps.html │ │ │ ├── BsForm.textProps.html │ │ │ ├── BsForm.textareaProps.html │ │ │ ├── BsTable.columnsConfigFace.html │ │ │ ├── BsTable.loadDataFace.html │ │ │ ├── BsTable.pagingConfigFace.html │ │ │ └── BsTable.tableConfigFace.html │ │ ├── modules.html │ │ └── modules │ │ │ ├── BsButtons.html │ │ │ ├── BsDialog.html │ │ │ ├── BsDialog_BsFormDialog.html │ │ │ ├── BsDialog_BsListDialog.html │ │ │ ├── BsEditTable.html │ │ │ ├── BsForm.html │ │ │ ├── BsForm_components_BsCascader.html │ │ │ ├── BsForm_components_BsCheckbox.html │ │ │ ├── BsForm_components_BsCollapse.html │ │ │ ├── BsForm_components_BsDate.html │ │ │ ├── BsForm_components_BsDateRange.html │ │ │ ├── BsForm_components_BsInput.html │ │ │ ├── BsForm_components_BsNumber.html │ │ │ ├── BsForm_components_BsNumberRange.html │ │ │ ├── BsForm_components_BsPasswod.html │ │ │ ├── BsForm_components_BsRadio.html │ │ │ ├── BsForm_components_BsSelect.html │ │ │ ├── BsForm_components_BsSwitch.html │ │ │ ├── BsForm_components_BsText.html │ │ │ ├── BsForm_components_BsTextarea.html │ │ │ └── BsTable.html │ └── image │ │ └── README │ │ └── 1693816439592.png └── workbox-5b385ed2.js ├── jest.config.js ├── package.json ├── packages ├── components │ ├── bsButtons │ │ └── index.ts │ ├── bsCascader │ │ └── index.ts │ ├── bsCheckbox │ │ └── index.ts │ ├── bsCollapse │ │ └── index.ts │ ├── bsDate │ │ └── index.ts │ ├── bsDateRange │ │ └── index.ts │ ├── bsDialog │ │ └── index.ts │ ├── bsEditTable │ │ └── index.ts │ ├── bsForm │ │ └── index.ts │ ├── bsFormDialog │ │ └── index.ts │ ├── bsInput │ │ └── index.ts │ ├── bsListDialog │ │ └── index.ts │ ├── bsNumber │ │ └── index.ts │ ├── bsNumberRange │ │ └── index.ts │ ├── bsRadio │ │ └── index.ts │ ├── bsSelect │ │ └── index.ts │ ├── bsSwitch │ │ └── index.ts │ ├── bsTable │ │ └── index.ts │ └── bsText │ │ └── index.ts └── index.ts ├── public ├── favicon.ico ├── img │ └── icons │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── android-chrome-maskable-192x192.png │ │ ├── android-chrome-maskable-512x512.png │ │ ├── apple-touch-icon-120x120.png │ │ ├── apple-touch-icon-152x152.png │ │ ├── apple-touch-icon-180x180.png │ │ ├── apple-touch-icon-60x60.png │ │ ├── apple-touch-icon-76x76.png │ │ ├── apple-touch-icon.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── msapplication-icon-144x144.png │ │ ├── mstile-150x150.png │ │ └── safari-pinned-tab.svg ├── index.html ├── robots.txt └── static │ ├── apiDocs2 │ ├── .nojekyll │ ├── assets │ │ ├── highlight.css │ │ ├── icons.css │ │ ├── icons.png │ │ ├── icons@2x.png │ │ ├── main.js │ │ ├── search.js │ │ ├── style.css │ │ ├── widgets.png │ │ └── widgets@2x.png │ ├── index.html │ ├── interfaces │ │ ├── BsButtons.buttonFace.html │ │ ├── BsDialog.dialogFace.html │ │ ├── BsDialog_BsFormDialog.dialogFormFace.html │ │ ├── BsDialog_BsFormDialog.dialogFormShowConfigFace.html │ │ ├── BsDialog_BsListDialog.dialogListFace.html │ │ ├── BsDialog_BsListDialog.dialogListShowConfigFace.html │ │ ├── BsEditTable.editTableColumnsItemConfig.html │ │ ├── BsEditTable.editTableConfigFace.html │ │ ├── BsForm.cascaderProps.html │ │ ├── BsForm.checkboxProps.html │ │ ├── BsForm.collapseProps.html │ │ ├── BsForm.dateProps.html │ │ ├── BsForm.dateRangeProps.html │ │ ├── BsForm.editTableProps.html │ │ ├── BsForm.formConfig.html │ │ ├── BsForm.inputProps.html │ │ ├── BsForm.numberProps.html │ │ ├── BsForm.numberRangeProps.html │ │ ├── BsForm.passwordProps.html │ │ ├── BsForm.radioProps.html │ │ ├── BsForm.renderProps.html │ │ ├── BsForm.selectProps.html │ │ ├── BsForm.switchProps.html │ │ ├── BsForm.textProps.html │ │ ├── BsForm.textareaProps.html │ │ ├── BsTable.columnsConfigFace.html │ │ ├── BsTable.loadDataFace.html │ │ ├── BsTable.pagingConfigFace.html │ │ └── BsTable.tableConfigFace.html │ ├── modules.html │ └── modules │ │ ├── BsButtons.html │ │ ├── BsDialog.html │ │ ├── BsDialog_BsFormDialog.html │ │ ├── BsDialog_BsListDialog.html │ │ ├── BsEditTable.html │ │ ├── BsForm.html │ │ ├── BsForm_components_BsCascader.html │ │ ├── BsForm_components_BsCheckbox.html │ │ ├── BsForm_components_BsCollapse.html │ │ ├── BsForm_components_BsDate.html │ │ ├── BsForm_components_BsDateRange.html │ │ ├── BsForm_components_BsInput.html │ │ ├── BsForm_components_BsNumber.html │ │ ├── BsForm_components_BsNumberRange.html │ │ ├── BsForm_components_BsPasswod.html │ │ ├── BsForm_components_BsRadio.html │ │ ├── BsForm_components_BsSelect.html │ │ ├── BsForm_components_BsSwitch.html │ │ ├── BsForm_components_BsText.html │ │ ├── BsForm_components_BsTextarea.html │ │ └── BsTable.html │ └── image │ └── README │ └── 1693816439592.png ├── rollup.config.js ├── src ├── App.vue ├── assets │ ├── css │ │ └── reset.css │ └── logo.png ├── components │ ├── BsButtons │ │ ├── index.tsx │ │ ├── interface │ │ │ └── index.ts │ │ └── style.module.scss │ ├── BsDialog │ │ ├── BsFormDialog │ │ │ └── index.tsx │ │ ├── BsListDialog │ │ │ └── index.tsx │ │ ├── index.tsx │ │ └── interface │ │ │ └── index.ts │ ├── BsEditTable │ │ ├── BsEditTableItem.tsx │ │ ├── index.tsx │ │ ├── interface │ │ │ └── index.ts │ │ ├── style.module.scss │ │ └── toolFn.tsx │ ├── BsForm │ │ ├── components │ │ │ ├── BsCascader.tsx │ │ │ ├── BsCheckbox.tsx │ │ │ ├── BsCollapse.tsx │ │ │ ├── BsDate.tsx │ │ │ ├── BsDateRange.tsx │ │ │ ├── BsInput.tsx │ │ │ ├── BsNumber.tsx │ │ │ ├── BsNumberRange.tsx │ │ │ ├── BsPasswod.tsx │ │ │ ├── BsRadio.tsx │ │ │ ├── BsSelect.tsx │ │ │ ├── BsSwitch.tsx │ │ │ ├── BsText.tsx │ │ │ ├── BsTextarea.tsx │ │ │ └── index.ts │ │ ├── index.tsx │ │ ├── interface │ │ │ └── index.ts │ │ ├── style.module.scss │ │ └── toolFn.ts │ ├── BsTable │ │ ├── BsTableItem.tsx │ │ ├── index.tsx │ │ ├── interface │ │ │ └── index.ts │ │ └── style.module.scss │ └── CustomDynamicComponent.tsx ├── examples │ ├── api │ │ └── index.vue │ ├── dialog │ │ └── index.vue │ ├── editTable │ │ └── index.vue │ ├── form │ │ └── index.vue │ └── home │ │ └── index.vue ├── layout │ ├── FullPageLayout.vue │ └── LRLayout.vue ├── local │ ├── components │ │ └── BaseMenu │ │ │ ├── index.tsx │ │ │ └── style.module.scss │ └── utils │ │ └── index.tsx ├── main.ts ├── registerServiceWorker.ts ├── router │ ├── index.ts │ └── route.ts ├── shims-vue.d.ts └── utils │ ├── common.ts │ ├── index.ts │ └── validator.ts ├── tests └── unit │ └── example.spec.ts ├── ts-shim.d.ts ├── tsconfig.json ├── typedoc.config.js └── vue.config.js /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | not ie 11 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,ts,tsx,vue}] 2 | indent_style = space 3 | indent_size = 2 4 | trim_trailing_whitespace = true 5 | insert_final_newline = true 6 | -------------------------------------------------------------------------------- /.env.npm: -------------------------------------------------------------------------------- 1 | ### 2 | # @Author: 陈宇环 3 | # @Date: 2023-05-26 11:21:51 4 | # @LastEditTime: 2023-05-26 11:21:54 5 | # @LastEditors: 陈宇环 6 | # @Description: 7 | ### 8 | ENV = 'npm' -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true, 5 | }, 6 | extends: [ 7 | 'plugin:vue/vue3-recommended', 8 | 'eslint:recommended', 9 | '@vue/eslint-config-typescript/recommended', 10 | ], 11 | parserOptions: { 12 | ecmaVersion: 2018, 13 | parser: '@typescript-eslint/parser', 14 | }, 15 | rules: { 16 | 'vue/multi-word-component-names': [ 17 | 'error', 18 | { 19 | ignores: ['index'], // 需要忽略的组件名 20 | }, 21 | ], 22 | 'no-unused-vars': 'off', 23 | 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 24 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 25 | 'no-var': 'error', // 禁止使用var 26 | 'prefer-const': 'error', // 建议使用const 27 | 'consistent-this': ['warn', 'self', 'vm'], // this只能取self为别名 28 | 'no-new-object': 'error', // 禁止Object构造函数,请使用字面值创建对象 29 | 'object-shorthand': ['error', 'always'], // 要求对象字面量简写语法(函数简写) 30 | 'quote-props': ['error', 'as-needed'], // 对象属性名称只有必要的才使用引号 31 | 'no-whitespace-before-property': 'error', // 禁止访问属性前面有空格(obj. key) 32 | 'no-array-constructor': 'error', // 禁止Array构造函数,请使用字面量值创建数组 33 | 'array-callback-return': 'error', // 数组方法都必须return (from、every、filter、find、findIndex、map、reduce、reduceRight、some、sort) 34 | 'prefer-destructuring': 'error', // 数组对象使用解构的方式获取属性值 35 | 'rest-spread-spacing': ['error', 'never'], // 扩展运算符及其表达式之间不允许有空格 36 | quotes: ['warn', 'single'], // 必须字符串单引号 37 | 'no-eval': 'warn', // 禁用 eval() 38 | 'no-new-func': 'error', // 禁用Function构造函数 39 | 'no-param-reassign': 'error', // 禁止修改函数参数 ["error", { "props": true }] 这个可以禁止修改对象 40 | 'template-curly-spacing': 'error', // 模板字符串`${}`中,{}中不允许空格(${a}) 41 | 'arrow-parens': ['error', 'always'], // 必须写箭头函数参数括号 42 | // 'arrow-body-style': ['error', 'as-needed'], // 箭头函数体大括号{}能省则必须省略 43 | // 'arrow-body-style': 'off', // 箭头函数体大括号{}能省则必须省略 44 | 'no-duplicate-imports': ['error', { includeExports: true }], // 一个路径只 import 一次 45 | 'dot-notation': 'error', // 访问属性时使用点符号,禁用['key']模式 46 | 'no-multi-assign': 'error', // 禁用连续赋值(a=b=c=3) 47 | eqeqeq: ['error', 'smart'], // 强制使用===或者!== 48 | 'no-unneeded-ternary': 'error', // 避免没必要的三目运算符 49 | curly: 'error', // 关键字之后不允许省略大括号 if() {} 50 | 'brace-style': 'error', // 关键字之后大括号换行规则(左大括号在同一行) 51 | 'spaced-comment': ['error', 'always'], // 注释(//或者/** */)文案前后需要添加空格 52 | // 'multiline-comment-style': ['error', 'starred-block'], // 禁止连续的单行注释(连续单行注释需要改成多行注释) 53 | // indent: ['error', 2, { SwitchCase: 1 }], // 统一的缩进为2 个别语法可以通过第三个参数控制 // https://cn.eslint.org/docs/rules/indent 54 | '@typescript-eslint/indent': ['error', 2, { SwitchCase: 1 }], 55 | 'space-before-blocks': 'error', // 块元素前面需要有空格 56 | 'keyword-spacing': 'error', // 要求在关键字之前至少有一个空格 && 要求在关键字之后至少有一个空格 57 | 'space-infix-ops': 'error', // 运算符两端必须添加空格(a === b) 58 | 'no-multiple-empty-lines': ['error', { max: 2 }], // 不允许多个空行 59 | 'space-in-parens': ['error', 'never'], // 圆括号两端不空格 60 | 'array-bracket-spacing': ['error', 'never'], // 方括号前后禁止空格 ([1, 2, 3]) 61 | 'object-curly-spacing': ['error', 'always'], // 花括号前后都需要空格 ({ a:1 }) 62 | 'comma-spacing': ['error', { before: false, after: true }], // 禁止在逗号前使用空格 && 要求在逗号后使用一个或多个空格 63 | 'func-call-spacing': ['error', 'never'], // 禁止在函数名和左括号之间有空格(仅函数调用) 64 | 'key-spacing': 'error', // 在对象的字面量属性中, 冒号前禁止空格,冒号必须空格 65 | 'no-trailing-spaces': ['error', { skipBlankLines: true }], // 非空白行行末禁止出现空格符 66 | 'comma-style': ['error', 'last'], // 禁止前置逗号(要求逗号放在数组元素、对象属性或变量声明之后,且在同一行) 67 | 'comma-dangle': ['error', 'always-multiline'], // 当最后一个元素或属性与闭括号 ] 或 } 在 不同的行时,要求使用拖尾逗号;当在 同一行时,禁止使用拖尾逗号。 68 | semi: ['error', 'never'], // 行后面禁止使用; 69 | camelcase: 'error', // 变量必须驼峰(通过监测_) 70 | 'new-cap': ['error', { capIsNew: false }], // 要求调用 new 操作符时有首字母大写的函数(构造函数大写)"capIsNew": false 允许调用首字符大写的函数 71 | 'space-before-function-paren': ['error', 'never'], // 禁止函数圆括号之前有一个空格 72 | 'arrow-spacing': 'error', // 箭头函数=>前必须加空格(() => {}) 73 | 'no-async-promise-executor': 'off', // 允许promise函数async 74 | 75 | // ts 76 | '@typescript-eslint/no-var-requires': 'off', 77 | '@typescript-eslint/no-explicit-any': 'off', // 去除any校验 78 | '@typescript-eslint/explicit-module-boundary-types': 'off', 79 | // '@typescript-eslint/no-empty-function': ['error', { "allow": ["arrowFunctions"]}], 80 | }, 81 | globals: { 82 | defineProps: 'readonly', 83 | defineEmits: 'readonly', 84 | defineExpose: 'readonly', 85 | withDefaults: 'readonly', 86 | }, 87 | overrides: [ 88 | { 89 | files: [ 90 | '**/__tests__/*.{j,t}s?(x)', 91 | '**/tests/unit/**/*.spec.{j,t}s?(x)', 92 | ], 93 | env: { 94 | jest: true, 95 | }, 96 | }, 97 | ], 98 | } 99 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | lib 5 | es 6 | iife 7 | types 8 | librollup 9 | package-lock.json 10 | 11 | 12 | # local env files 13 | .env.local 14 | .env.*.local 15 | 16 | # Log files 17 | npm-debug.log* 18 | yarn-debug.log* 19 | yarn-error.log* 20 | pnpm-debug.log* 21 | 22 | # Editor directories and files 23 | .idea 24 | .vscode 25 | *.suo 26 | *.ntvs* 27 | *.njsproj 28 | *.sln 29 | *.sw? 30 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .vscode 3 | buildConfig/ 4 | node_modules/ 5 | packages/ 6 | public/ 7 | src/ 8 | tests/ 9 | dist/ 10 | types/ 11 | examples/ 12 | localComponents/ 13 | router/ 14 | package-lock.json 15 | .browserslistrc 16 | .editorconfig 17 | .eslintrc.js 18 | babel.config.js 19 | jest.config.js 20 | vue.config.js 21 | tsconfig.json 22 | .env.npm 23 | ts-shim.d.ts 24 | rollup.config.js 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # backstage-vue3 2 | 3 | 一款基于Vue3,JSON配置化UI组件库,同时兼容element-ui、ant-design-vue 4 | 5 | # 接入指南 6 | 7 | ## 安装 8 | 9 | npm i backstage-vue3 10 | 11 | ## 添加babel按需引入插件 12 | 13 | ```js 14 | module.exports = { 15 | ... 16 | plugins: [ 17 | ..., 18 | [ // 本次增加 19 | 'import', 20 | { // 按需引入backstage-vue3组件 21 | libraryName: 'backstage-vue3', 22 | libraryDirectory: 'lib', 23 | customStyleName: () => { 24 | return 'backstage-vue3/lib/css/index.css' 25 | }, 26 | }, 27 | ], 28 | ] 29 | } 30 | ``` 31 | 32 | ## 使用 33 | 34 | ```js 35 | 40 | 41 | import { BsTable, BsForm } from 'backstage-vue3' 42 | ``` 43 | 44 | ## ant-design-vue使用 45 | 46 | 如果你是使用的element-plus你可以直接忽略此步骤,如果你使用的是ant-design-vue,你需要在main.js顶部添加 47 | 48 | ```js 49 | window.uiLanguage = 'ant' 50 | ``` 51 | 52 | # 注意事项 53 | 54 | **按需引入会对组件传入的所有props进行类型校验,如下:** 55 | 56 | ![1693816439592](/backstage-vue3/static/image/README/1693816439592.png) 57 | 58 | 可以直接导入内置提供的接口,来保证传入的数据符合类型校验: 59 | 60 | ```js 61 | 66 | 67 | import { BsTable, BsForm, formConfig } from 'backstage-vue3' 68 | 69 | const config = ref({ 70 | ... 71 | }) 72 | ``` 73 | 74 | # 示例页面 75 | 76 | https://chenyuhuan.gitee.io/backstage-vue3/#/home 77 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset', 4 | [ 5 | '@babel/preset-env', 6 | { 7 | targets: { 8 | browsers: ['last 2 versions'], 9 | }, 10 | debug: false, 11 | }, 12 | ], 13 | ], 14 | plugins: [ 15 | '@babel/plugin-transform-runtime', 16 | [ // 本次增加 17 | 'import', 18 | { // 按需引入backstage-vue3组件 19 | libraryName: 'backstage-vue3', 20 | libraryDirectory: 'lib', 21 | customStyleName: () => { 22 | return 'backstage-vue3/lib/css/index.css' 23 | }, 24 | }, 25 | ], 26 | ], 27 | } 28 | -------------------------------------------------------------------------------- /buildConfig/build.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 陈宇环 3 | * @Date: 2023-05-26 10:50:26 4 | * @LastEditTime: 2023-09-04 15:58:52 5 | * @LastEditors: 陈宇环 6 | * @Description: 7 | */ 8 | 9 | const { defineConfig } = require('@vue/cli-service') 10 | const path = require('path') 11 | const resolve = (dir) => { 12 | path.resolve(__dirname, '../' + dir) 13 | } 14 | 15 | const config = defineConfig({ 16 | transpileDependencies: true, 17 | productionSourceMap: false, 18 | publicPath: '/backstage-vue3', 19 | outputDir: 'docs', 20 | configureWebpack: { 21 | resolve: { 22 | alias: { 23 | '@': resolve(__dirname, 'src'), 24 | }, 25 | }, 26 | }, 27 | chainWebpack: (chain) => { 28 | const oneofsMap = chain.module.rule(/\.js|jsx$/).oneOfs.store 29 | oneofsMap.forEach((item) => { 30 | item 31 | .use('babel-loader') 32 | .loader('babel-loader') 33 | }) 34 | }, 35 | }) 36 | 37 | module.exports = config 38 | -------------------------------------------------------------------------------- /buildConfig/npmBuild.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 陈宇环 3 | * @Date: 2023-05-26 10:50:26 4 | * @LastEditTime: 2023-07-06 10:52:25 5 | * @LastEditors: 陈宇环 6 | * @Description: 7 | */ 8 | 9 | // const { defineConfig } = require('@vue/cli-service') 10 | const path = require('path') 11 | const fs = require('fs') 12 | const { join } = path 13 | 14 | const TerserPlugin = require('terser-webpack-plugin') 15 | 16 | const resolve = (dir) => { 17 | return path.resolve(__dirname, '../' + dir) 18 | } 19 | 20 | /** 21 | * @desc 驼峰转横杠 22 | * @param {*} str 23 | */ 24 | function upperCasetoLine(str) { 25 | let temp = str.replace(/[A-Z]/g, function(match) { 26 | return '-' + match.toLowerCase() 27 | }) 28 | if (temp.slice(0, 1) === '-') { 29 | temp = temp.slice(1) 30 | } 31 | return temp 32 | } 33 | 34 | // 将packages目录下的子目录组成如下格式数组'bs-form': resolve('packages/components/easeForm.ts') 35 | function getComponentEntries(path) { 36 | const files = fs.readdirSync(resolve(path)) 37 | const componentEntries = files.reduce((fileObj, item) => { 38 | // 文件路径 39 | const itemPath = join(path, item) 40 | // 在文件夹中 41 | const isDir = fs.statSync(itemPath).isDirectory() 42 | const [name, suffix] = item.split('.') 43 | 44 | // 文件中的入口文件 45 | if (isDir) { 46 | fileObj[`${upperCasetoLine(item)}`] = resolve(join(itemPath, 'index.ts')) 47 | } else if (suffix === 'js') { 48 | // 文件夹外的入口文件 49 | fileObj[name] = resolve(`${itemPath}`) 50 | } 51 | return fileObj 52 | }, {}) 53 | return componentEntries 54 | } 55 | 56 | const config = { 57 | outputDir: resolve('lib'), 58 | configureWebpack: { 59 | resolve: { 60 | alias: { 61 | '@': resolve('src'), 62 | }, 63 | }, 64 | entry: { 65 | index: resolve('packages/index.ts'), 66 | ...getComponentEntries('packages/components'), 67 | }, 68 | output: { 69 | // 文件名称 70 | filename: '[name]/index.js', 71 | // 构建依赖类型 72 | libraryTarget: 'umd', 73 | umdNamedDefine: false, 74 | // 依赖输出 75 | libraryExport: 'default', 76 | // 依赖名称 77 | library: 'backstage-vue3', 78 | }, 79 | externals: { 80 | 'element-plus': 'element-plus', 81 | vue: 'vue', 82 | }, 83 | optimization: { 84 | minimize: true, 85 | minimizer: [ 86 | new TerserPlugin({ 87 | terserOptions: { 88 | output: { 89 | comments: false, // 去掉注释 90 | }, 91 | }, 92 | }), 93 | ], 94 | // splitChunks: { 95 | // chunks: 'all', 96 | // cacheGroups: { 97 | // // 第三方模块 98 | // vendor: { 99 | // name: 'common', // chunk 名称 100 | // priority: 1, // 权限更高,优先抽离,重要!!! 101 | // test: '/node_modules/', // 一般第三方模块都是从node_modules引进来如lodash 102 | // minSize: 0, // 大小限制 103 | // minChunks: 1, // 最少复用过几次 104 | // }, 105 | // }, 106 | // }, 107 | }, 108 | }, 109 | css: { 110 | sourceMap: true, 111 | extract: { 112 | filename: '[name]/style.css', 113 | }, 114 | }, 115 | chainWebpack: (config) => { 116 | config.optimization.delete('splitChunks') 117 | config.plugins.delete('copy') 118 | config.plugins.delete('preload') 119 | config.plugins.delete('prefetch') 120 | config.plugins.delete('html') 121 | config.plugins.delete('hmr') 122 | config.entryPoints.delete('app') 123 | }, 124 | } 125 | 126 | module.exports = config 127 | -------------------------------------------------------------------------------- /docs/css/146.3a49afba.css: -------------------------------------------------------------------------------- 1 | .style-module_width100__IAGRa{flex:1;width:100%!important}.style-module_BsForm__xhkDE .bs-edit-table .el-form-item.is-success .el-input__wrapper{box-shadow:0 0 0 1px var(--el-input-border-color,var(--el-border-color)) inset}.style-module_BsForm__xhkDE .bs-edit-table .ep-form-item.is-success .ep-input__wrapper{box-shadow:0 0 0 1px var(--ep-input-border-color,var(--ep-border-color)) inset}.style-module_BsDateRange__9N8iS,.style-module_BsDateRange__9N8iS .el-input-number,.style-module_BsDateRange__9N8iS .ep-input-number,.style-module_BsNumber__MhnQc,.style-module_BsNumber__MhnQc .el-input-number,.style-module_BsNumber__MhnQc .ep-input-number{width:100%}.style-module_BsDateRange__9N8iS .el-input-number .el-input__wrapper,.style-module_BsDateRange__9N8iS .ep-input-number .ep-input__wrapper,.style-module_BsNumber__MhnQc .el-input-number .el-input__wrapper,.style-module_BsNumber__MhnQc .ep-input-number .ep-input__wrapper{padding-left:11px!important;padding-right:11px!important}.style-module_BsDateRange__9N8iS .textLeft .el-input__inner,.style-module_BsDateRange__9N8iS .textLeft .ep-input__inner,.style-module_BsNumber__MhnQc .textLeft .el-input__inner,.style-module_BsNumber__MhnQc .textLeft .ep-input__inner{text-align:left}.style-module_BsDateRange__9N8iS .ant-form-item-control-input-content,.style-module_BsNumber__MhnQc .ant-form-item-control-input-content{display:flex}.style-module_BsNumberRange__7K0Iy .style-module_noControls__dJr3D .el-input__inner,.style-module_BsNumberRange__7K0Iy .style-module_noControls__dJr3D .ep-input__inner{text-align:left}.style-module_BsNumberRange__7K0Iy .ant-form-item-control-input-content{display:flex}.style-module_BaseCollapse__0kXYL .el-collapse-item__header,.style-module_BaseCollapse__0kXYL .el-collapse-item__wrap,.style-module_BaseCollapse__0kXYL .ep-collapse-item__header,.style-module_BaseCollapse__0kXYL .ep-collapse-item__wrap{background-color:#f1f1f1}.style-module_BaseCollapse__0kXYL .el-collapse-item__content,.style-module_BaseCollapse__0kXYL .el-collapse-item__header,.style-module_BaseCollapse__0kXYL .ep-collapse-item__content,.style-module_BaseCollapse__0kXYL .ep-collapse-item__header{padding:0 0 0 10px}.style-module_BsEditTable__r5mI2{background-color:#fff;border-radius:3px;display:flex;flex-direction:column;justify-content:space-between;width:100%}.style-module_BsEditTable__r5mI2 .style-module_table__OGdX9{flex:1}.style-module_BsEditTable__r5mI2 .style-module_table__OGdX9 .el-radio__label,.style-module_BsEditTable__r5mI2 .style-module_table__OGdX9 .ep-radio__label{display:none}.style-module_BsEditTable__r5mI2 .ant-form-item,.style-module_BsEditTable__r5mI2 .el-form-item,.style-module_BsEditTable__r5mI2 .ep-form-item{margin-bottom:0}.style-module_BsEditTable__r5mI2 .el-form-item__content,.style-module_BsEditTable__r5mI2 .ep-form-item__content{flex-wrap:inherit}.style-module_BsEditTable__r5mI2 .ant-form-item-control{position:relative}.style-module_BsEditTable__r5mI2 .ant-form-item-explain-connected{left:0;position:absolute;top:100%;white-space:nowrap}.style-module_BsTable__qrv-k{background-color:#fff;border-radius:3px;display:flex;flex-direction:column;height:100%;justify-content:space-between;width:100%}.style-module_BsTable__qrv-k .style-module_table__GWlq8{flex:1}.style-module_BsTable__qrv-k .style-module_table__GWlq8 .style-module_rowRadio__r34-P .el-radio__label,.style-module_BsTable__qrv-k .style-module_table__GWlq8 .style-module_rowRadio__r34-P .ep-radio__label{display:none} -------------------------------------------------------------------------------- /docs/css/331.3a49afba.css: -------------------------------------------------------------------------------- 1 | .style-module_width100__IAGRa{flex:1;width:100%!important}.style-module_BsForm__xhkDE .bs-edit-table .el-form-item.is-success .el-input__wrapper{box-shadow:0 0 0 1px var(--el-input-border-color,var(--el-border-color)) inset}.style-module_BsForm__xhkDE .bs-edit-table .ep-form-item.is-success .ep-input__wrapper{box-shadow:0 0 0 1px var(--ep-input-border-color,var(--ep-border-color)) inset}.style-module_BsDateRange__9N8iS,.style-module_BsDateRange__9N8iS .el-input-number,.style-module_BsDateRange__9N8iS .ep-input-number,.style-module_BsNumber__MhnQc,.style-module_BsNumber__MhnQc .el-input-number,.style-module_BsNumber__MhnQc .ep-input-number{width:100%}.style-module_BsDateRange__9N8iS .el-input-number .el-input__wrapper,.style-module_BsDateRange__9N8iS .ep-input-number .ep-input__wrapper,.style-module_BsNumber__MhnQc .el-input-number .el-input__wrapper,.style-module_BsNumber__MhnQc .ep-input-number .ep-input__wrapper{padding-left:11px!important;padding-right:11px!important}.style-module_BsDateRange__9N8iS .textLeft .el-input__inner,.style-module_BsDateRange__9N8iS .textLeft .ep-input__inner,.style-module_BsNumber__MhnQc .textLeft .el-input__inner,.style-module_BsNumber__MhnQc .textLeft .ep-input__inner{text-align:left}.style-module_BsDateRange__9N8iS .ant-form-item-control-input-content,.style-module_BsNumber__MhnQc .ant-form-item-control-input-content{display:flex}.style-module_BsNumberRange__7K0Iy .style-module_noControls__dJr3D .el-input__inner,.style-module_BsNumberRange__7K0Iy .style-module_noControls__dJr3D .ep-input__inner{text-align:left}.style-module_BsNumberRange__7K0Iy .ant-form-item-control-input-content{display:flex}.style-module_BaseCollapse__0kXYL .el-collapse-item__header,.style-module_BaseCollapse__0kXYL .el-collapse-item__wrap,.style-module_BaseCollapse__0kXYL .ep-collapse-item__header,.style-module_BaseCollapse__0kXYL .ep-collapse-item__wrap{background-color:#f1f1f1}.style-module_BaseCollapse__0kXYL .el-collapse-item__content,.style-module_BaseCollapse__0kXYL .el-collapse-item__header,.style-module_BaseCollapse__0kXYL .ep-collapse-item__content,.style-module_BaseCollapse__0kXYL .ep-collapse-item__header{padding:0 0 0 10px}.style-module_BsEditTable__r5mI2{background-color:#fff;border-radius:3px;display:flex;flex-direction:column;justify-content:space-between;width:100%}.style-module_BsEditTable__r5mI2 .style-module_table__OGdX9{flex:1}.style-module_BsEditTable__r5mI2 .style-module_table__OGdX9 .el-radio__label,.style-module_BsEditTable__r5mI2 .style-module_table__OGdX9 .ep-radio__label{display:none}.style-module_BsEditTable__r5mI2 .ant-form-item,.style-module_BsEditTable__r5mI2 .el-form-item,.style-module_BsEditTable__r5mI2 .ep-form-item{margin-bottom:0}.style-module_BsEditTable__r5mI2 .el-form-item__content,.style-module_BsEditTable__r5mI2 .ep-form-item__content{flex-wrap:inherit}.style-module_BsEditTable__r5mI2 .ant-form-item-control{position:relative}.style-module_BsEditTable__r5mI2 .ant-form-item-explain-connected{left:0;position:absolute;top:100%;white-space:nowrap}.style-module_BsTable__qrv-k{background-color:#fff;border-radius:3px;display:flex;flex-direction:column;height:100%;justify-content:space-between;width:100%}.style-module_BsTable__qrv-k .style-module_table__GWlq8{flex:1}.style-module_BsTable__qrv-k .style-module_table__GWlq8 .style-module_rowRadio__r34-P .el-radio__label,.style-module_BsTable__qrv-k .style-module_table__GWlq8 .style-module_rowRadio__r34-P .ep-radio__label{display:none} -------------------------------------------------------------------------------- /docs/css/545.15d37a70.css: -------------------------------------------------------------------------------- 1 | .style-module_width100__IAGRa{flex:1;width:100%!important}.style-module_BsForm__xhkDE .bs-edit-table .el-form-item.is-success .el-input__wrapper{box-shadow:0 0 0 1px var(--el-input-border-color,var(--el-border-color)) inset}.style-module_BsForm__xhkDE .bs-edit-table .ep-form-item.is-success .ep-input__wrapper{box-shadow:0 0 0 1px var(--ep-input-border-color,var(--ep-border-color)) inset}.style-module_BsDateRange__9N8iS,.style-module_BsDateRange__9N8iS .el-input-number,.style-module_BsDateRange__9N8iS .ep-input-number,.style-module_BsNumber__MhnQc,.style-module_BsNumber__MhnQc .el-input-number,.style-module_BsNumber__MhnQc .ep-input-number{width:100%}.style-module_BsDateRange__9N8iS .el-input-number .el-input__wrapper,.style-module_BsDateRange__9N8iS .ep-input-number .ep-input__wrapper,.style-module_BsNumber__MhnQc .el-input-number .el-input__wrapper,.style-module_BsNumber__MhnQc .ep-input-number .ep-input__wrapper{padding-left:11px!important;padding-right:11px!important}.style-module_BsDateRange__9N8iS .textLeft .el-input__inner,.style-module_BsDateRange__9N8iS .textLeft .ep-input__inner,.style-module_BsNumber__MhnQc .textLeft .el-input__inner,.style-module_BsNumber__MhnQc .textLeft .ep-input__inner{text-align:left}.style-module_BsDateRange__9N8iS .ant-form-item-control-input-content,.style-module_BsNumber__MhnQc .ant-form-item-control-input-content{display:flex}.style-module_BsNumberRange__7K0Iy .style-module_noControls__dJr3D .el-input__inner,.style-module_BsNumberRange__7K0Iy .style-module_noControls__dJr3D .ep-input__inner{text-align:left}.style-module_BsNumberRange__7K0Iy .ant-form-item-control-input-content{display:flex}.style-module_BaseCollapse__0kXYL .el-collapse-item__header,.style-module_BaseCollapse__0kXYL .el-collapse-item__wrap,.style-module_BaseCollapse__0kXYL .ep-collapse-item__header,.style-module_BaseCollapse__0kXYL .ep-collapse-item__wrap{background-color:#f1f1f1}.style-module_BaseCollapse__0kXYL .el-collapse-item__content,.style-module_BaseCollapse__0kXYL .el-collapse-item__header,.style-module_BaseCollapse__0kXYL .ep-collapse-item__content,.style-module_BaseCollapse__0kXYL .ep-collapse-item__header{padding:0 0 0 10px}.style-module_BsEditTable__r5mI2{background-color:#fff;border-radius:3px;display:flex;flex-direction:column;justify-content:space-between;width:100%}.style-module_BsEditTable__r5mI2 .style-module_table__OGdX9{flex:1}.style-module_BsEditTable__r5mI2 .style-module_table__OGdX9 .el-radio__label,.style-module_BsEditTable__r5mI2 .style-module_table__OGdX9 .ep-radio__label{display:none}.style-module_BsEditTable__r5mI2 .ant-form-item,.style-module_BsEditTable__r5mI2 .el-form-item,.style-module_BsEditTable__r5mI2 .ep-form-item{margin-bottom:0}.style-module_BsEditTable__r5mI2 .el-form-item__content,.style-module_BsEditTable__r5mI2 .ep-form-item__content{flex-wrap:inherit}.style-module_BsEditTable__r5mI2 .ant-form-item-control{position:relative}.style-module_BsEditTable__r5mI2 .ant-form-item-explain-connected{left:0;position:absolute;top:100%;white-space:nowrap}.style-module_BsTable__qrv-k{background-color:#fff;border-radius:3px;display:flex;flex-direction:column;height:100%;justify-content:space-between;width:100%}.style-module_BsTable__qrv-k .style-module_table__GWlq8{flex:1}.style-module_BsTable__qrv-k .style-module_table__GWlq8 .style-module_rowRadio__r34-P .el-radio__label,.style-module_BsTable__qrv-k .style-module_table__GWlq8 .style-module_rowRadio__r34-P .ep-radio__label{display:none}.FullPageLayout[data-v-42f9beaf]{height:100%;display:flex;flex-direction:column;justify-content:space-between;overflow:hidden}.FullPageLayout .auto-strut[data-v-42f9beaf]{background-color:#fff;padding:15px 15px 0}.FullPageLayout .flex1[data-v-42f9beaf]{padding:0 15px;flex:1;overflow:hidden;background-color:#fff}.home[data-v-66da4d90]{display:flex;flex-direction:column;overflow:hidden;height:100%}.home .FullPageLayout[data-v-66da4d90]{flex:1} -------------------------------------------------------------------------------- /docs/css/653.3a49afba.css: -------------------------------------------------------------------------------- 1 | .style-module_width100__IAGRa{flex:1;width:100%!important}.style-module_BsForm__xhkDE .bs-edit-table .el-form-item.is-success .el-input__wrapper{box-shadow:0 0 0 1px var(--el-input-border-color,var(--el-border-color)) inset}.style-module_BsForm__xhkDE .bs-edit-table .ep-form-item.is-success .ep-input__wrapper{box-shadow:0 0 0 1px var(--ep-input-border-color,var(--ep-border-color)) inset}.style-module_BsDateRange__9N8iS,.style-module_BsDateRange__9N8iS .el-input-number,.style-module_BsDateRange__9N8iS .ep-input-number,.style-module_BsNumber__MhnQc,.style-module_BsNumber__MhnQc .el-input-number,.style-module_BsNumber__MhnQc .ep-input-number{width:100%}.style-module_BsDateRange__9N8iS .el-input-number .el-input__wrapper,.style-module_BsDateRange__9N8iS .ep-input-number .ep-input__wrapper,.style-module_BsNumber__MhnQc .el-input-number .el-input__wrapper,.style-module_BsNumber__MhnQc .ep-input-number .ep-input__wrapper{padding-left:11px!important;padding-right:11px!important}.style-module_BsDateRange__9N8iS .textLeft .el-input__inner,.style-module_BsDateRange__9N8iS .textLeft .ep-input__inner,.style-module_BsNumber__MhnQc .textLeft .el-input__inner,.style-module_BsNumber__MhnQc .textLeft .ep-input__inner{text-align:left}.style-module_BsDateRange__9N8iS .ant-form-item-control-input-content,.style-module_BsNumber__MhnQc .ant-form-item-control-input-content{display:flex}.style-module_BsNumberRange__7K0Iy .style-module_noControls__dJr3D .el-input__inner,.style-module_BsNumberRange__7K0Iy .style-module_noControls__dJr3D .ep-input__inner{text-align:left}.style-module_BsNumberRange__7K0Iy .ant-form-item-control-input-content{display:flex}.style-module_BaseCollapse__0kXYL .el-collapse-item__header,.style-module_BaseCollapse__0kXYL .el-collapse-item__wrap,.style-module_BaseCollapse__0kXYL .ep-collapse-item__header,.style-module_BaseCollapse__0kXYL .ep-collapse-item__wrap{background-color:#f1f1f1}.style-module_BaseCollapse__0kXYL .el-collapse-item__content,.style-module_BaseCollapse__0kXYL .el-collapse-item__header,.style-module_BaseCollapse__0kXYL .ep-collapse-item__content,.style-module_BaseCollapse__0kXYL .ep-collapse-item__header{padding:0 0 0 10px}.style-module_BsEditTable__r5mI2{background-color:#fff;border-radius:3px;display:flex;flex-direction:column;justify-content:space-between;width:100%}.style-module_BsEditTable__r5mI2 .style-module_table__OGdX9{flex:1}.style-module_BsEditTable__r5mI2 .style-module_table__OGdX9 .el-radio__label,.style-module_BsEditTable__r5mI2 .style-module_table__OGdX9 .ep-radio__label{display:none}.style-module_BsEditTable__r5mI2 .ant-form-item,.style-module_BsEditTable__r5mI2 .el-form-item,.style-module_BsEditTable__r5mI2 .ep-form-item{margin-bottom:0}.style-module_BsEditTable__r5mI2 .el-form-item__content,.style-module_BsEditTable__r5mI2 .ep-form-item__content{flex-wrap:inherit}.style-module_BsEditTable__r5mI2 .ant-form-item-control{position:relative}.style-module_BsEditTable__r5mI2 .ant-form-item-explain-connected{left:0;position:absolute;top:100%;white-space:nowrap}.style-module_BsTable__qrv-k{background-color:#fff;border-radius:3px;display:flex;flex-direction:column;height:100%;justify-content:space-between;width:100%}.style-module_BsTable__qrv-k .style-module_table__GWlq8{flex:1}.style-module_BsTable__qrv-k .style-module_table__GWlq8 .style-module_rowRadio__r34-P .el-radio__label,.style-module_BsTable__qrv-k .style-module_table__GWlq8 .style-module_rowRadio__r34-P .ep-radio__label{display:none} -------------------------------------------------------------------------------- /docs/css/824.4916a807.css: -------------------------------------------------------------------------------- 1 | .iframe[data-v-3016bb9d]{width:100%;height:calc(100vh - 36px)} -------------------------------------------------------------------------------- /docs/css/app.4ec54d1f.css: -------------------------------------------------------------------------------- 1 | *{margin:0;padding:0}.DwMH2zo43NU_GLGM4J0T{width:auto;height:100%;background-color:#30364c;overflow-y:auto;overflow-x:hidden}.DwMH2zo43NU_GLGM4J0T.width230{width:180px}.DwMH2zo43NU_GLGM4J0T .el-menu-vertical:not(.ep-menu--collapse){height:100%;width:180px}.LRLayout[data-v-5299b008]{height:100vh;display:flex;justify-content:space-between;overflow:hidden;box-sizing:border-box}.LRLayout .aside[data-v-5299b008]{height:100vh;overflow:auto;position:relative}.LRLayout .main[data-v-5299b008]{padding:15px;box-sizing:border-box;flex:1;overflow:auto;background-color:#f1f1f1} -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/docs/favicon.ico -------------------------------------------------------------------------------- /docs/img/icons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/docs/img/icons/android-chrome-192x192.png -------------------------------------------------------------------------------- /docs/img/icons/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/docs/img/icons/android-chrome-512x512.png -------------------------------------------------------------------------------- /docs/img/icons/android-chrome-maskable-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/docs/img/icons/android-chrome-maskable-192x192.png -------------------------------------------------------------------------------- /docs/img/icons/android-chrome-maskable-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/docs/img/icons/android-chrome-maskable-512x512.png -------------------------------------------------------------------------------- /docs/img/icons/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/docs/img/icons/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /docs/img/icons/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/docs/img/icons/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /docs/img/icons/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/docs/img/icons/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /docs/img/icons/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/docs/img/icons/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /docs/img/icons/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/docs/img/icons/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /docs/img/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/docs/img/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /docs/img/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/docs/img/icons/favicon-16x16.png -------------------------------------------------------------------------------- /docs/img/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/docs/img/icons/favicon-32x32.png -------------------------------------------------------------------------------- /docs/img/icons/msapplication-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/docs/img/icons/msapplication-icon-144x144.png -------------------------------------------------------------------------------- /docs/img/icons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/docs/img/icons/mstile-150x150.png -------------------------------------------------------------------------------- /docs/img/icons/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | backstage-vue3
-------------------------------------------------------------------------------- /docs/js/146.3cd1c469.js: -------------------------------------------------------------------------------- 1 | "use strict";(self["webpackChunkbackstage_vue3"]=self["webpackChunkbackstage_vue3"]||[]).push([[146],{8315:function(e,n,t){t.d(n,{n:function(){return l}});var a=t(5290),l=function(e){var n=a.Z.resolve({path:"/api",query:{url:e}});window.open(n.href)}},6906:function(e,n,t){var a=t(4126);t(5918),t(2160),t(6623),t(6866),t(229),t(3602),t(1146),t(186),t(6278),t(3773),t(7300),t(9640),t(1661),t(6999),t(7576),t(5936),t(1245),t(6289),t(1944),t(8395),t(8010),t(2059),t(7088),t(3331),t(3978),a.BsForm.install=function(e){e.component(a.BsForm.name,a.BsForm)};var l=a.BsForm;n.ZP=a.BsForm},8146:function(e,n,t){t.r(n),t.d(n,{default:function(){return v}});var a=t(6906),l=t(124),u=t(8534),r=t(3396),o=t(4870),i=t(8315),s=(0,r._)("a",{href:"https://gitee.com/chenyuhuan/backstage-vue3/blob/master/src/examples/form/index.vue"},"https://gitee.com/chenyuhuan/backstage-vue3/blob/master/src/examples/form/index.vue",-1),p=(0,r._)("span",null,"表单",-1),c=(0,r._)("span",null,"搜索条件",-1),m=(0,r._)("span",null,"文本表单",-1),d=(0,r._)("span",null,"表单联动",-1),f=(0,r.aZ)({__name:"index",setup:function(e){var n=function(e,n,t){if(!n)return t(new Error("Please input the age"));setTimeout((function(){Number.isInteger(n)?n<18?t(new Error("Age must be greater than 18")):t():t(new Error("Please input digits"))}),1e3)},t=(0,o.iH)(),f=(0,o.iH)(),g=(0,o.iH)({notOpBtn:!0,colNum:8,columns:[{type:"input",prop:"name",label:"姓名",required:!0},{type:"number",prop:"age",label:"年龄",rules:[{validator:n,trigger:"change"}]},{type:"select",prop:"sex",label:"性别",options:[{label:"男",value:1},{label:"女",value:2}]},{type:"select",prop:"department",label:"部门",bottomNoteRender:function(){return(0,r.Wm)("div",{style:{color:"#999",padding:"3px 0"}},[(0,r.Uk)("接口获取下拉菜单")])},options:{type:"api",getData:function(){return new Promise((function(e){setTimeout((function(){e([{label:"信息技术部",value:1},{label:"财务部",value:2}])}),1e3)}))}}}]}),v=(0,o.iH)(),b=(0,o.iH)(),h=(0,o.iH)({colNum:8,columns:[{type:"input",prop:"name",label:"姓名",required:!0},{type:"number",prop:"age",label:"年龄",rules:[{required:!0,message:"请输入年龄",trigger:"change"},{min:3,max:5,message:"Length should be 3 to 5",trigger:"change"}]},{type:"select",prop:"sex",label:"性别",options:[{label:"男",value:1},{label:"女",value:2}]},{type:"select",prop:"department",label:"部门",options:{type:"api",getData:function(){return new Promise((function(e){setTimeout((function(){e([{label:"信息技术部",value:1},{label:"财务部",value:2}])}),1e3)}))}}}],searchFn:function(){console.log(b.value)},searchBtnProps:{size:"default"},resetBtnProps:{size:"default",type:""},resetFn:function(){console.log("resetFn")}}),y=function(){var e=(0,u.Z)((0,l.Z)().mark((function e(){var n;return(0,l.Z)().wrap((function(e){while(1)switch(e.prev=e.next){case 0:return e.next=2,t.value.validate();case 2:n=e.sent,console.log(n);case 4:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}(),w=(0,o.iH)(),x=(0,o.iH)({name:"张三",age:18,sex:1,department:1}),_=(0,o.iH)({notOpBtn:!0,colNum:8,columns:[{type:"input",prop:"name",label:"姓名",required:!0},{type:"number",prop:"age",label:"年龄",rules:[{required:!0,message:"请输入年龄",trigger:"change"},{min:3,max:5,message:"Length should be 3 to 5",trigger:"change"}]},{type:"select",prop:"sex",label:"性别",options:[{label:"男",value:1},{label:"女",value:2}]},{type:"select",prop:"department",label:"部门",options:{type:"api",getData:function(){return new Promise((function(e){setTimeout((function(){e([{label:"信息技术部",value:1},{label:"财务部",value:2}])}),1e3)}))}}}],textMode:!0}),k=(0,o.iH)(),B=(0,o.iH)(),P=(0,o.iH)({notOpBtn:!0,colNum:8,columns:[{type:"input",prop:"name",label:"姓名",required:!0,change:function(e){"张三"===e.value&&(B.value.age=10)}},{type:"number",prop:"age",label:"年龄",rules:[{required:!0,message:"请输入年龄",trigger:"change"},{min:3,max:5,message:"Length should be 3 to 5",trigger:"change"}]},{type:"select",prop:"sex",label:"性别",options:[{label:"男",value:1},{label:"女",value:2}],change:function(e){var n=P.value.columns.findIndex((function(e){return"heigth"===e.prop})),t=P.value.columns.findIndex((function(e){return"department"===e.prop}));1===e.value?(n&&(P.value.columns[n].hide=!1),t&&(P.value.columns[t].required=!0)):(n&&(P.value.columns[n].hide=!0),t&&(P.value.columns[t].required=!0))}},{type:"input",prop:"heigth",label:"身高",hide:!0},{type:"select",prop:"department",label:"部门",options:{type:"api",getData:function(){return new Promise((function(e){setTimeout((function(){e([{label:"信息技术部",value:1},{label:"财务部",value:2}])}),1e3)}))}}}]});return function(e,n){var l=(0,r.up)("el-alert"),u=(0,r.up)("el-button"),F=(0,r.up)("el-card");return(0,r.wg)(),(0,r.iD)(r.HY,null,[(0,r.Wm)(l,{title:"",type:"success",style:{"margin-bottom":"15px"}},{default:(0,r.w5)((function(){return[(0,r.Uk)(" 示例代码地址:"),s]})),_:1}),(0,r.Wm)(F,{shadow:"always","body-style":{padding:"15px"}},{header:(0,r.w5)((function(){return[p,(0,r._)("a",{style:{"margin-left":"50px"},href:"javascript:",onClick:n[0]||(n[0]=function(e){return(0,o.SU)(i.n)("/static/apiDocs2/modules/BsForm.html")})},"API地址")]})),default:(0,r.w5)((function(){return[(0,r.Wm)((0,o.SU)(a.ZP),{ref_key:"BsFormDom",ref:t,modelValue:f.value,"onUpdate:modelValue":n[1]||(n[1]=function(e){return f.value=e}),config:g.value},null,8,["modelValue","config"]),(0,r.Wm)(u,{type:"primary",onClick:y},{default:(0,r.w5)((function(){return[(0,r.Uk)(" 提交 ")]})),_:1})]})),_:1}),(0,r.Wm)(F,{shadow:"always",style:{"margin-top":"15px"},"body-style":{padding:"15px"}},{header:(0,r.w5)((function(){return[c]})),default:(0,r.w5)((function(){return[(0,r.Wm)((0,o.SU)(a.ZP),{ref_key:"BsFormDom2",ref:v,modelValue:b.value,"onUpdate:modelValue":n[2]||(n[2]=function(e){return b.value=e}),config:h.value},null,8,["modelValue","config"])]})),_:1}),(0,r.Wm)(F,{shadow:"always",style:{"margin-top":"15px"},"body-style":{padding:"15px"}},{header:(0,r.w5)((function(){return[m]})),default:(0,r.w5)((function(){return[(0,r.Wm)((0,o.SU)(a.ZP),{ref_key:"BsFormDom3",ref:w,modelValue:x.value,"onUpdate:modelValue":n[3]||(n[3]=function(e){return x.value=e}),config:_.value},null,8,["modelValue","config"])]})),_:1}),(0,r.Wm)(F,{shadow:"always",style:{"margin-top":"15px"},"body-style":{padding:"15px"}},{header:(0,r.w5)((function(){return[d]})),default:(0,r.w5)((function(){return[(0,r.Wm)((0,o.SU)(a.ZP),{ref_key:"BsFormDom4",ref:k,modelValue:B.value,"onUpdate:modelValue":n[4]||(n[4]=function(e){return B.value=e}),config:P.value},null,8,["modelValue","config"])]})),_:1})],64)}}});const g=f;var v=g}}]); -------------------------------------------------------------------------------- /docs/js/824.23fdc32b.js: -------------------------------------------------------------------------------- 1 | "use strict";(self["webpackChunkbackstage_vue3"]=self["webpackChunkbackstage_vue3"]||[]).push([[824],{4824:function(e,a,u){u.r(a),u.d(a,{default:function(){return v}});var r=u(3396),t=u(4870),n=u(2483),c={class:"api"},s=["src"],i=(0,r.aZ)({__name:"index",setup:function(e){var a,u,i=(0,n.tv)(),l=null!==(a=null===(u=i.currentRoute.value.query)||void 0===u?void 0:u.url)&&void 0!==a?a:"/static/apiDocs2/index.html";return function(e,a){return(0,r.wg)(),(0,r.iD)("div",c,[(0,t.SU)(l)?((0,r.wg)(),(0,r.iD)("iframe",{key:0,class:"iframe",src:"/backstage-vue3"+(0,t.SU)(l),scrolling:"auto",frameborder:"0"},null,8,s)):(0,r.kq)("",!0)])}}}),l=u(89);const o=(0,l.Z)(i,[["__scopeId","data-v-3016bb9d"]]);var v=o}}]); -------------------------------------------------------------------------------- /docs/manifest.json: -------------------------------------------------------------------------------- 1 | {"name":"backstage-vue3","short_name":"backstage-vue3","theme_color":"#4DBA87","icons":[{"src":"./img/icons/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"./img/icons/android-chrome-512x512.png","sizes":"512x512","type":"image/png"},{"src":"./img/icons/android-chrome-maskable-192x192.png","sizes":"192x192","type":"image/png","purpose":"maskable"},{"src":"./img/icons/android-chrome-maskable-512x512.png","sizes":"512x512","type":"image/png","purpose":"maskable"}],"start_url":".","display":"standalone","background_color":"#000000"} -------------------------------------------------------------------------------- /docs/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /docs/static/apiDocs2/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /docs/static/apiDocs2/assets/highlight.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --light-hl-0: #000000; 3 | --dark-hl-0: #D4D4D4; 4 | --light-hl-1: #267F99; 5 | --dark-hl-1: #4EC9B0; 6 | --light-hl-2: #001080; 7 | --dark-hl-2: #9CDCFE; 8 | --light-hl-3: #008000; 9 | --dark-hl-3: #6A9955; 10 | --light-hl-4: #A31515; 11 | --dark-hl-4: #CE9178; 12 | --light-hl-5: #795E26; 13 | --dark-hl-5: #DCDCAA; 14 | --light-hl-6: #0000FF; 15 | --dark-hl-6: #569CD6; 16 | --light-hl-7: #AF00DB; 17 | --dark-hl-7: #C586C0; 18 | --light-hl-8: #800000; 19 | --dark-hl-8: #808080; 20 | --light-hl-9: #FF0000; 21 | --dark-hl-9: #9CDCFE; 22 | --light-hl-10: #CD3131; 23 | --dark-hl-10: #F44747; 24 | --light-hl-11: #0070C1; 25 | --dark-hl-11: #4FC1FF; 26 | --light-code-background: #F5F5F5; 27 | --dark-code-background: #1E1E1E; 28 | } 29 | 30 | @media (prefers-color-scheme: light) { :root { 31 | --hl-0: var(--light-hl-0); 32 | --hl-1: var(--light-hl-1); 33 | --hl-2: var(--light-hl-2); 34 | --hl-3: var(--light-hl-3); 35 | --hl-4: var(--light-hl-4); 36 | --hl-5: var(--light-hl-5); 37 | --hl-6: var(--light-hl-6); 38 | --hl-7: var(--light-hl-7); 39 | --hl-8: var(--light-hl-8); 40 | --hl-9: var(--light-hl-9); 41 | --hl-10: var(--light-hl-10); 42 | --hl-11: var(--light-hl-11); 43 | --code-background: var(--light-code-background); 44 | } } 45 | 46 | @media (prefers-color-scheme: dark) { :root { 47 | --hl-0: var(--dark-hl-0); 48 | --hl-1: var(--dark-hl-1); 49 | --hl-2: var(--dark-hl-2); 50 | --hl-3: var(--dark-hl-3); 51 | --hl-4: var(--dark-hl-4); 52 | --hl-5: var(--dark-hl-5); 53 | --hl-6: var(--dark-hl-6); 54 | --hl-7: var(--dark-hl-7); 55 | --hl-8: var(--dark-hl-8); 56 | --hl-9: var(--dark-hl-9); 57 | --hl-10: var(--dark-hl-10); 58 | --hl-11: var(--dark-hl-11); 59 | --code-background: var(--dark-code-background); 60 | } } 61 | 62 | body.light { 63 | --hl-0: var(--light-hl-0); 64 | --hl-1: var(--light-hl-1); 65 | --hl-2: var(--light-hl-2); 66 | --hl-3: var(--light-hl-3); 67 | --hl-4: var(--light-hl-4); 68 | --hl-5: var(--light-hl-5); 69 | --hl-6: var(--light-hl-6); 70 | --hl-7: var(--light-hl-7); 71 | --hl-8: var(--light-hl-8); 72 | --hl-9: var(--light-hl-9); 73 | --hl-10: var(--light-hl-10); 74 | --hl-11: var(--light-hl-11); 75 | --code-background: var(--light-code-background); 76 | } 77 | 78 | body.dark { 79 | --hl-0: var(--dark-hl-0); 80 | --hl-1: var(--dark-hl-1); 81 | --hl-2: var(--dark-hl-2); 82 | --hl-3: var(--dark-hl-3); 83 | --hl-4: var(--dark-hl-4); 84 | --hl-5: var(--dark-hl-5); 85 | --hl-6: var(--dark-hl-6); 86 | --hl-7: var(--dark-hl-7); 87 | --hl-8: var(--dark-hl-8); 88 | --hl-9: var(--dark-hl-9); 89 | --hl-10: var(--dark-hl-10); 90 | --hl-11: var(--dark-hl-11); 91 | --code-background: var(--dark-code-background); 92 | } 93 | 94 | .hl-0 { color: var(--hl-0); } 95 | .hl-1 { color: var(--hl-1); } 96 | .hl-2 { color: var(--hl-2); } 97 | .hl-3 { color: var(--hl-3); } 98 | .hl-4 { color: var(--hl-4); } 99 | .hl-5 { color: var(--hl-5); } 100 | .hl-6 { color: var(--hl-6); } 101 | .hl-7 { color: var(--hl-7); } 102 | .hl-8 { color: var(--hl-8); } 103 | .hl-9 { color: var(--hl-9); } 104 | .hl-10 { color: var(--hl-10); } 105 | .hl-11 { color: var(--hl-11); } 106 | pre, code { background: var(--code-background); } 107 | -------------------------------------------------------------------------------- /docs/static/apiDocs2/assets/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/docs/static/apiDocs2/assets/icons.png -------------------------------------------------------------------------------- /docs/static/apiDocs2/assets/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/docs/static/apiDocs2/assets/icons@2x.png -------------------------------------------------------------------------------- /docs/static/apiDocs2/assets/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/docs/static/apiDocs2/assets/widgets.png -------------------------------------------------------------------------------- /docs/static/apiDocs2/assets/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/docs/static/apiDocs2/assets/widgets@2x.png -------------------------------------------------------------------------------- /docs/static/apiDocs2/interfaces/BsTable.columnsConfigFace.html: -------------------------------------------------------------------------------- 1 | columnsConfigFace | backstage-vue3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Interface columnsConfigFace

Legend

  • Variable
  • Type alias
  • Interface

Settings

Theme

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/static/image/README/1693816439592.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/docs/static/image/README/1693816439592.png -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel' 3 | } 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backstage-vue3", 3 | "version": "0.2.21", 4 | "private": false, 5 | "main": "lib/index/index.js", 6 | "module": "es/index/index.mjs", 7 | "types": "lib/types/packages/index.d.ts", 8 | "scripts": { 9 | "serve": "vue-cli-service serve", 10 | "build": "vue-cli-service build", 11 | "test:unit": "vue-cli-service test:unit", 12 | "lint": "vue-cli-service lint", 13 | "typedoc": "typedoc --options typedoc.config.js", 14 | "docs": "npm run typedoc & npm run build", 15 | "lib": "tsc && vue-cli-service build --mode npm", 16 | "lib:rollup": "rollup -c --bundleConfigAsCjs", 17 | "lib:iife": "FORMAT=iife rollup -c --bundleConfigAsCjs" 18 | }, 19 | "dependencies": { 20 | "ant-design-vue": "^3.2.16", 21 | "backstage-vue3": "^0.2.19", 22 | "core-js": "^3.8.3", 23 | "element-plus": "^2.3.5", 24 | "register-service-worker": "^1.7.2", 25 | "vue": "^3.2.13", 26 | "vue-router": "^4.2.4" 27 | }, 28 | "devDependencies": { 29 | "@babel/core": "^7.22.9", 30 | "@babel/preset-env": "^7.22.9", 31 | "@rollup/plugin-alias": "^5.0.0", 32 | "@rollup/plugin-babel": "^6.0.3", 33 | "@rollup/plugin-commonjs": "^25.0.3", 34 | "@rollup/plugin-node-resolve": "^15.1.0", 35 | "@rollup/plugin-strip": "^3.0.2", 36 | "@rollup/plugin-terser": "^0.4.3", 37 | "@rollup/plugin-typescript": "^11.1.2", 38 | "@types/jest": "^27.0.1", 39 | "@typescript-eslint/eslint-plugin": "^5.4.0", 40 | "@typescript-eslint/parser": "^5.4.0", 41 | "@vue/cli-plugin-babel": "~5.0.0", 42 | "@vue/cli-plugin-eslint": "~5.0.0", 43 | "@vue/cli-plugin-pwa": "~5.0.0", 44 | "@vue/cli-plugin-typescript": "~5.0.0", 45 | "@vue/cli-plugin-unit-jest": "~5.0.0", 46 | "@vue/cli-service": "~5.0.0", 47 | "@vue/eslint-config-standard": "^6.1.0", 48 | "@vue/eslint-config-typescript": "^9.1.0", 49 | "@vue/test-utils": "^2.0.0-0", 50 | "@vue/vue3-jest": "^27.0.0-alpha.1", 51 | "autoprefixer": "^8.0.0", 52 | "babel-jest": "^27.0.6", 53 | "babel-plugin-component": "^1.1.1", 54 | "babel-plugin-import": "^1.13.8", 55 | "cssnano": "^6.0.1", 56 | "dayjs": "^1.11.7", 57 | "eslint": "^7.32.0", 58 | "eslint-plugin-import": "^2.25.3", 59 | "eslint-plugin-node": "^11.1.0", 60 | "eslint-plugin-promise": "^5.1.0", 61 | "eslint-plugin-vue": "^8.0.3", 62 | "jest": "^27.0.5", 63 | "postcss": "^8.4.27", 64 | "rollup": "^3.27.0", 65 | "rollup-plugin-postcss": "^4.0.2", 66 | "sass": "^1.32.7", 67 | "sass-loader": "^12.0.0", 68 | "terser-webpack-plugin": "^5.3.9", 69 | "ts-jest": "^27.0.4", 70 | "ttypescript": "^1.5.15", 71 | "typedoc": "^0.22.18", 72 | "typescript": "~4.5.5", 73 | "typescript-transform-paths": "^3.4.6" 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /packages/components/bsButtons/index.ts: -------------------------------------------------------------------------------- 1 | import button from '../../../src/components/BsButtons/index' 2 | 3 | button.install = function(Vue: any) { 4 | Vue.component(button.name, button) 5 | } 6 | 7 | export default button 8 | export const BsButtons = button 9 | 10 | export * from '../../../src/components/BsButtons/interface/index' -------------------------------------------------------------------------------- /packages/components/bsCascader/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 陈宇环 3 | * @Date: 2023-05-26 11:48:21 4 | * @LastEditTime: 2023-07-03 15:16:48 5 | * @LastEditors: 陈宇环 6 | * @Description: 7 | */ 8 | import cascader from '../../../src/components/BsForm/components/BsCascader' 9 | 10 | cascader.install = function(Vue: any) { 11 | Vue.component(cascader.name, cascader) 12 | } 13 | 14 | export default cascader 15 | 16 | 17 | export const BsCascader = cascader 18 | 19 | export * from '../../../src/components/BsForm/interface/index' -------------------------------------------------------------------------------- /packages/components/bsCheckbox/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 陈宇环 3 | * @Date: 2023-05-26 11:48:21 4 | * @LastEditTime: 2023-07-03 15:18:10 5 | * @LastEditors: 陈宇环 6 | * @Description: 7 | */ 8 | import checkbox from '../../../src/components/BsForm/components/BsCheckbox' 9 | 10 | checkbox.install = function(Vue: any) { 11 | Vue.component(checkbox.name, checkbox) 12 | } 13 | 14 | export default checkbox 15 | 16 | 17 | export const BsCheckbox = checkbox 18 | 19 | export * from '../../../src/components/BsForm/interface/index' -------------------------------------------------------------------------------- /packages/components/bsCollapse/index.ts: -------------------------------------------------------------------------------- 1 | import collapse from '../../../src/components/BsForm/components/BsCollapse' 2 | 3 | collapse.install = function(Vue: any) { 4 | Vue.component(collapse.name, collapse) 5 | } 6 | 7 | export default collapse 8 | 9 | export const BsCollapse = collapse 10 | 11 | export * from '../../../src/components/BsForm/interface/index' 12 | -------------------------------------------------------------------------------- /packages/components/bsDate/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 陈宇环 3 | * @Date: 2023-05-26 11:48:21 4 | * @LastEditTime: 2023-07-03 15:20:37 5 | * @LastEditors: 陈宇环 6 | * @Description: 7 | */ 8 | import date from '../../../src/components/BsForm/components/BsDate' 9 | 10 | date.install = function(Vue: any) { 11 | Vue.component(date.name, date) 12 | } 13 | 14 | export default date 15 | 16 | export const BsDate = date 17 | 18 | export * from '../../../src/components/BsForm/interface/index' -------------------------------------------------------------------------------- /packages/components/bsDateRange/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 陈宇环 3 | * @Date: 2023-05-26 11:48:21 4 | * @LastEditTime: 2023-07-03 15:21:28 5 | * @LastEditors: 陈宇环 6 | * @Description: 7 | */ 8 | import dateRange from '../../../src/components/BsForm/components/BsDateRange' 9 | 10 | dateRange.install = function(Vue: any) { 11 | Vue.component(dateRange.name, dateRange) 12 | } 13 | 14 | export default dateRange 15 | 16 | export const BsDateRange = dateRange 17 | 18 | export * from '../../../src/components/BsForm/interface/index' -------------------------------------------------------------------------------- /packages/components/bsDialog/index.ts: -------------------------------------------------------------------------------- 1 | import dialog from '../../../src/components/BsDialog/index' 2 | 3 | dialog.install = function(Vue: any) { 4 | Vue.component(dialog.name, dialog) 5 | } 6 | 7 | export default dialog 8 | export const BsDialog = dialog 9 | 10 | export * from '../../../src/components/BsDialog/interface/index' -------------------------------------------------------------------------------- /packages/components/bsEditTable/index.ts: -------------------------------------------------------------------------------- 1 | import editTable from '../../../src/components/BsEditTable/index' 2 | 3 | editTable.install = function(Vue: any) { 4 | Vue.component(editTable.name, editTable) 5 | } 6 | 7 | export default editTable 8 | export const BsEditTable = editTable 9 | 10 | export * from '../../../src/components/BsEditTable/interface/index' -------------------------------------------------------------------------------- /packages/components/bsForm/index.ts: -------------------------------------------------------------------------------- 1 | import form from '../../../src/components/BsForm/index' 2 | 3 | form.install = function(Vue: any) { 4 | Vue.component(form.name, form) 5 | } 6 | 7 | export default form 8 | export const BsForm = form 9 | 10 | export * from '../../../src/components/BsForm/interface/index' -------------------------------------------------------------------------------- /packages/components/bsFormDialog/index.ts: -------------------------------------------------------------------------------- 1 | import formDialog from '../../../src/components/BsDialog/BsFormDialog/index' 2 | 3 | formDialog.install = function(Vue: any) { 4 | Vue.component(formDialog.name, formDialog) 5 | } 6 | 7 | export default formDialog 8 | export const BsFormDialog = formDialog 9 | 10 | export * from '../../../src/components/BsDialog/interface/index' -------------------------------------------------------------------------------- /packages/components/bsInput/index.ts: -------------------------------------------------------------------------------- 1 | import input from '../../../src/components/BsForm/components/BsInput' 2 | 3 | input.install = function(Vue: any) { 4 | Vue.component(input.name, input) 5 | } 6 | 7 | export default input 8 | 9 | export const BsInput = input 10 | 11 | export * from '../../../src/components/BsForm/interface/index' -------------------------------------------------------------------------------- /packages/components/bsListDialog/index.ts: -------------------------------------------------------------------------------- 1 | import listDialog from '../../../src/components/BsDialog/BsListDialog/index' 2 | 3 | listDialog.install = function(Vue: any) { 4 | Vue.component(listDialog.name, listDialog) 5 | } 6 | 7 | export default listDialog 8 | export const BsListDialog = listDialog 9 | 10 | export * from '../../../src/components/BsDialog/interface/index' -------------------------------------------------------------------------------- /packages/components/bsNumber/index.ts: -------------------------------------------------------------------------------- 1 | import number from '../../../src/components/BsForm/components/BsNumber' 2 | 3 | number.install = function(Vue: any) { 4 | Vue.component(number.name, number) 5 | } 6 | 7 | export default number 8 | 9 | export const BsNumber = number 10 | 11 | export * from '../../../src/components/BsForm/interface/index' -------------------------------------------------------------------------------- /packages/components/bsNumberRange/index.ts: -------------------------------------------------------------------------------- 1 | import numberRange from '../../../src/components/BsForm/components/BsNumberRange' 2 | 3 | numberRange.install = function(Vue: any) { 4 | Vue.component(numberRange.name, numberRange) 5 | } 6 | 7 | export default numberRange 8 | 9 | export const BsNumberRange = numberRange 10 | 11 | export * from '../../../src/components/BsForm/interface/index' -------------------------------------------------------------------------------- /packages/components/bsRadio/index.ts: -------------------------------------------------------------------------------- 1 | import radio from '../../../src/components/BsForm/components/BsRadio' 2 | 3 | radio.install = function(Vue: any) { 4 | Vue.component(radio.name, radio) 5 | } 6 | 7 | export default radio 8 | 9 | export const BsRadio = radio 10 | 11 | export * from '../../../src/components/BsForm/interface/index' -------------------------------------------------------------------------------- /packages/components/bsSelect/index.ts: -------------------------------------------------------------------------------- 1 | import select from '../../../src/components/BsForm/components/BsSelect' 2 | 3 | select.install = function(Vue: any) { 4 | Vue.component(select.name, select) 5 | } 6 | 7 | export default select 8 | 9 | export const BsSelect = select 10 | 11 | export * from '../../../src/components/BsForm/interface/index' -------------------------------------------------------------------------------- /packages/components/bsSwitch/index.ts: -------------------------------------------------------------------------------- 1 | import switchC from '../../../src/components/BsForm/components/BsSwitch' 2 | 3 | switchC.install = function(Vue: any) { 4 | Vue.component(switchC.name, switchC) 5 | } 6 | 7 | export default switchC 8 | 9 | export const BsSwitch = switchC 10 | 11 | export * from '../../../src/components/BsForm/interface/index' -------------------------------------------------------------------------------- /packages/components/bsTable/index.ts: -------------------------------------------------------------------------------- 1 | import table from '../../../src/components/BsTable/index' 2 | 3 | table.install = function(Vue: any) { 4 | Vue.component(table.name, BsTable) 5 | } 6 | 7 | export default table 8 | export const BsTable = table 9 | 10 | export * from '../../../src/components/BsTable/interface/index' -------------------------------------------------------------------------------- /packages/components/bsText/index.ts: -------------------------------------------------------------------------------- 1 | import text from '../../../src/components/BsForm/components/BsText' 2 | 3 | text.install = function(Vue: any) { 4 | Vue.component(text.name, text) 5 | } 6 | 7 | export default text 8 | 9 | export const BsText = text 10 | 11 | export * from '../../../src/components/BsForm/interface/index' -------------------------------------------------------------------------------- /packages/index.ts: -------------------------------------------------------------------------------- 1 | import BsForm from './components/bsForm' 2 | import BsCascader from './components/bsCascader' 3 | import BsCheckbox from './components/bsCheckbox' 4 | import BsDate from './components/bsDate' 5 | import BsDateRange from './components/bsDateRange' 6 | import BsInput from './components/bsInput' 7 | import BsNumber from './components/bsNumber' 8 | import BsNumberRange from './components/bsNumberRange' 9 | import BsRadio from './components/bsRadio' 10 | import BsSelect from './components/bsSelect' 11 | import BsSwitch from './components/bsSwitch' 12 | import BsText from './components/bsText' 13 | import BsTable from './components/bsTable' 14 | import BsButtons from './components/bsButtons' 15 | import BsCollapse from './components/bsCollapse' 16 | import BsEditTable from './components/bsEditTable' 17 | const components = [ 18 | BsForm, 19 | BsCascader, 20 | BsCheckbox, 21 | BsDate, 22 | BsDateRange, 23 | BsInput, 24 | BsNumber, 25 | BsNumberRange, 26 | BsRadio, 27 | BsSelect, 28 | BsSwitch, 29 | BsText, 30 | BsTable, 31 | BsButtons, 32 | BsCollapse, 33 | BsEditTable, 34 | ] // 组件集合 35 | const install = function(Vue: any) { 36 | // 注册所有的组件 37 | components.forEach((item) => { 38 | Vue.component(item.name, item) 39 | }) 40 | } 41 | // 如果是直接引入文件,就不用调用Vue.use() 42 | if (typeof window !== 'undefined' && window.Vue) { 43 | install(window.Vue) 44 | } 45 | 46 | export * from './components/bsForm' 47 | export * from './components/bsCascader' 48 | export * from './components/bsCheckbox' 49 | export * from './components/bsDate' 50 | export * from './components/bsDateRange' 51 | export * from './components/bsInput' 52 | export * from './components/bsNumber' 53 | export * from './components/bsNumberRange' 54 | export * from './components/bsRadio' 55 | export * from './components/bsSelect' 56 | export * from './components/bsSwitch' 57 | export * from './components/bsText' 58 | export * from './components/bsTable' 59 | export * from './components/bsButtons' 60 | export * from './components/bsCollapse' 61 | export * from './components/bsEditTable' 62 | export * from './components/bsDialog' 63 | export * from './components/bsFormDialog' 64 | export * from './components/bsListDialog' 65 | 66 | export default install 67 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/public/favicon.ico -------------------------------------------------------------------------------- /public/img/icons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/public/img/icons/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/img/icons/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/public/img/icons/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/img/icons/android-chrome-maskable-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/public/img/icons/android-chrome-maskable-192x192.png -------------------------------------------------------------------------------- /public/img/icons/android-chrome-maskable-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/public/img/icons/android-chrome-maskable-512x512.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/public/img/icons/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/public/img/icons/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/public/img/icons/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/public/img/icons/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/public/img/icons/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/public/img/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /public/img/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/public/img/icons/favicon-16x16.png -------------------------------------------------------------------------------- /public/img/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/public/img/icons/favicon-32x32.png -------------------------------------------------------------------------------- /public/img/icons/msapplication-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/public/img/icons/msapplication-icon-144x144.png -------------------------------------------------------------------------------- /public/img/icons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/public/img/icons/mstile-150x150.png -------------------------------------------------------------------------------- /public/img/icons/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /public/static/apiDocs2/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /public/static/apiDocs2/assets/highlight.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --light-hl-0: #000000; 3 | --dark-hl-0: #D4D4D4; 4 | --light-hl-1: #267F99; 5 | --dark-hl-1: #4EC9B0; 6 | --light-hl-2: #001080; 7 | --dark-hl-2: #9CDCFE; 8 | --light-hl-3: #008000; 9 | --dark-hl-3: #6A9955; 10 | --light-hl-4: #A31515; 11 | --dark-hl-4: #CE9178; 12 | --light-hl-5: #795E26; 13 | --dark-hl-5: #DCDCAA; 14 | --light-hl-6: #0000FF; 15 | --dark-hl-6: #569CD6; 16 | --light-hl-7: #AF00DB; 17 | --dark-hl-7: #C586C0; 18 | --light-hl-8: #800000; 19 | --dark-hl-8: #808080; 20 | --light-hl-9: #FF0000; 21 | --dark-hl-9: #9CDCFE; 22 | --light-hl-10: #CD3131; 23 | --dark-hl-10: #F44747; 24 | --light-hl-11: #0070C1; 25 | --dark-hl-11: #4FC1FF; 26 | --light-code-background: #F5F5F5; 27 | --dark-code-background: #1E1E1E; 28 | } 29 | 30 | @media (prefers-color-scheme: light) { :root { 31 | --hl-0: var(--light-hl-0); 32 | --hl-1: var(--light-hl-1); 33 | --hl-2: var(--light-hl-2); 34 | --hl-3: var(--light-hl-3); 35 | --hl-4: var(--light-hl-4); 36 | --hl-5: var(--light-hl-5); 37 | --hl-6: var(--light-hl-6); 38 | --hl-7: var(--light-hl-7); 39 | --hl-8: var(--light-hl-8); 40 | --hl-9: var(--light-hl-9); 41 | --hl-10: var(--light-hl-10); 42 | --hl-11: var(--light-hl-11); 43 | --code-background: var(--light-code-background); 44 | } } 45 | 46 | @media (prefers-color-scheme: dark) { :root { 47 | --hl-0: var(--dark-hl-0); 48 | --hl-1: var(--dark-hl-1); 49 | --hl-2: var(--dark-hl-2); 50 | --hl-3: var(--dark-hl-3); 51 | --hl-4: var(--dark-hl-4); 52 | --hl-5: var(--dark-hl-5); 53 | --hl-6: var(--dark-hl-6); 54 | --hl-7: var(--dark-hl-7); 55 | --hl-8: var(--dark-hl-8); 56 | --hl-9: var(--dark-hl-9); 57 | --hl-10: var(--dark-hl-10); 58 | --hl-11: var(--dark-hl-11); 59 | --code-background: var(--dark-code-background); 60 | } } 61 | 62 | body.light { 63 | --hl-0: var(--light-hl-0); 64 | --hl-1: var(--light-hl-1); 65 | --hl-2: var(--light-hl-2); 66 | --hl-3: var(--light-hl-3); 67 | --hl-4: var(--light-hl-4); 68 | --hl-5: var(--light-hl-5); 69 | --hl-6: var(--light-hl-6); 70 | --hl-7: var(--light-hl-7); 71 | --hl-8: var(--light-hl-8); 72 | --hl-9: var(--light-hl-9); 73 | --hl-10: var(--light-hl-10); 74 | --hl-11: var(--light-hl-11); 75 | --code-background: var(--light-code-background); 76 | } 77 | 78 | body.dark { 79 | --hl-0: var(--dark-hl-0); 80 | --hl-1: var(--dark-hl-1); 81 | --hl-2: var(--dark-hl-2); 82 | --hl-3: var(--dark-hl-3); 83 | --hl-4: var(--dark-hl-4); 84 | --hl-5: var(--dark-hl-5); 85 | --hl-6: var(--dark-hl-6); 86 | --hl-7: var(--dark-hl-7); 87 | --hl-8: var(--dark-hl-8); 88 | --hl-9: var(--dark-hl-9); 89 | --hl-10: var(--dark-hl-10); 90 | --hl-11: var(--dark-hl-11); 91 | --code-background: var(--dark-code-background); 92 | } 93 | 94 | .hl-0 { color: var(--hl-0); } 95 | .hl-1 { color: var(--hl-1); } 96 | .hl-2 { color: var(--hl-2); } 97 | .hl-3 { color: var(--hl-3); } 98 | .hl-4 { color: var(--hl-4); } 99 | .hl-5 { color: var(--hl-5); } 100 | .hl-6 { color: var(--hl-6); } 101 | .hl-7 { color: var(--hl-7); } 102 | .hl-8 { color: var(--hl-8); } 103 | .hl-9 { color: var(--hl-9); } 104 | .hl-10 { color: var(--hl-10); } 105 | .hl-11 { color: var(--hl-11); } 106 | pre, code { background: var(--code-background); } 107 | -------------------------------------------------------------------------------- /public/static/apiDocs2/assets/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/public/static/apiDocs2/assets/icons.png -------------------------------------------------------------------------------- /public/static/apiDocs2/assets/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/public/static/apiDocs2/assets/icons@2x.png -------------------------------------------------------------------------------- /public/static/apiDocs2/assets/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/public/static/apiDocs2/assets/widgets.png -------------------------------------------------------------------------------- /public/static/apiDocs2/assets/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/public/static/apiDocs2/assets/widgets@2x.png -------------------------------------------------------------------------------- /public/static/apiDocs2/interfaces/BsTable.columnsConfigFace.html: -------------------------------------------------------------------------------- 1 | columnsConfigFace | backstage-vue3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Interface columnsConfigFace

Legend

  • Variable
  • Type alias
  • Interface

Settings

Theme

Generated using TypeDoc

-------------------------------------------------------------------------------- /public/static/image/README/1693816439592.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/public/static/image/README/1693816439592.png -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import babel from '@rollup/plugin-babel' 2 | import terser from '@rollup/plugin-terser' 3 | import commonjs from '@rollup/plugin-commonjs' 4 | import typescript from '@rollup/plugin-typescript' 5 | import nodeResolve from '@rollup/plugin-node-resolve' 6 | import alias from '@rollup/plugin-alias' 7 | import strip from '@rollup/plugin-strip' 8 | import postcss from 'rollup-plugin-postcss' 9 | import autoprefixer from 'autoprefixer' 10 | import cssnano from 'cssnano' 11 | import path from 'path' 12 | import fs from 'fs' 13 | import ttypescript from 'ttypescript' 14 | 15 | const { join } = path 16 | 17 | 18 | const resolve = (dir) => { 19 | return path.resolve(__dirname, dir) 20 | } 21 | /** 22 | * @desc 驼峰转横杠 23 | * @param {*} str 24 | */ 25 | function upperCasetoLine(str) { 26 | let temp = str.replace(/[A-Z]/g, function(match) { 27 | return '-' + match.toLowerCase() 28 | }) 29 | if (temp.slice(0, 1) === '-') { 30 | temp = temp.slice(1) 31 | } 32 | return temp 33 | } 34 | 35 | // 将packages目录下的子目录组成如下格式数组'bs-form': resolve('packages/components/easeForm.ts') 36 | function getComponentEntries(path) { 37 | const files = fs.readdirSync(resolve(path)) 38 | const componentEntries = files.reduce((fileObj, item) => { 39 | // 文件路径 40 | const itemPath = join(path, item) 41 | // 在文件夹中 42 | const isDir = fs.statSync(itemPath).isDirectory() 43 | const [name, suffix] = item.split('.') 44 | 45 | // 文件中的入口文件 46 | if (isDir) { 47 | fileObj[`${upperCasetoLine(item)}`] = resolve(join(itemPath, 'index.ts')) 48 | } else if (suffix === 'js') { 49 | // 文件夹外的入口文件 50 | fileObj[name] = resolve(`${itemPath}`) 51 | } 52 | return fileObj 53 | }, {}) 54 | return componentEntries 55 | } 56 | function getConfig(format) { 57 | return { 58 | input: { 59 | index: resolve('packages/index.ts'), 60 | ...format !== 'iife' ? getComponentEntries('packages/components') : {}, 61 | }, 62 | output: 63 | { 64 | dir: format === 'cjs' ? 'lib' : format, 65 | format, 66 | // name该选项用于,在想要使用全局变量名来表示你的 bundle 时,输出格式必须指定为 iife 或 umd。同一个页面上的其他脚本可以通过这个变量名来访问你的 bundle 导出 67 | ...format === 'iife' ? { name: 'backstageVue3' } : {}, 68 | sourcemap: true, 69 | entryFileNames: `[name]/index.${format === 'es' ? 'm' : ''}js`, // 该选项用于指定 chunks 的入口文件模式 eg: bs-input/index.js 70 | chunkFileNames: `chunkFile/[name].${format === 'es' ? 'm' : ''}js`, // 该选项用于对代码分割中产生的 chunk 自定义命名 71 | }, 72 | plugins: [ 73 | alias({ 74 | // resolve: ['.jsx', '.js', '.tsx', '.ts', '.scss', '.d.ts'], 75 | entries: [{ 76 | find: '@', // 组件库用到的@替换为绝对路径 77 | replacement: resolve('src'), 78 | }], 79 | }), 80 | nodeResolve(), 81 | commonjs(), 82 | typescript({ 83 | typescript: ttypescript, // 如果需要自动生成(导出)类型定义文件,TSC 不会处理路径别名,需要引入 typescript-transform-paths 插件,以及 TTypescript 来转换路径别名为相对路径。 84 | sourceMap: false, 85 | declaration: format !== 'iife', // iife不要 d.ts文件 86 | declarationDir: `${format === 'cjs' ? 'lib' : format}/types`, 87 | // outDir: `${format === 'cjs' ? 'lib' : format}`, //默认情况下,ts编译后的js文件,与源文件都在同一个目录下。使用outDir选项可以指定编译后的文件所在的目录。清理之前编译生成的js文件。 88 | }), 89 | babel({ 90 | babelHelpers: 'runtime', 91 | exclude: 'node_modules/**', 92 | extensions: ['.js', '.jsx', '.ts', '.tsx'], 93 | }), 94 | postcss({ 95 | plugins: [ 96 | autoprefixer(), 97 | cssnano(), 98 | ], 99 | extract: 'css/index.css', 100 | }), 101 | strip(), // 用于从代码中删除 debugger 语句和函数。包括 assert.equal、console.log 102 | format === 'iife' && terser(), // 代码压缩 103 | ], 104 | external: [ 105 | 'vue', 106 | 'element-plus', 107 | 'ant-design-vue', 108 | 'vue-router', 109 | 'backstage-vue3', 110 | ], 111 | } 112 | } 113 | export default [ 114 | ...process.env.FORMAT === 'iife' ? [ 115 | getConfig('iife'), 116 | ] : [ 117 | getConfig('cjs'), 118 | getConfig('es'), 119 | ], 120 | ] 121 | 122 | 123 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 16 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /src/assets/css/reset.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenyuhuan1/backstage-vue3/de336feef0049adcc77ed98861f98b1b473b33a1/src/assets/logo.png -------------------------------------------------------------------------------- /src/components/BsButtons/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 陈宇环 3 | * @Date: 2023-05-10 16:10:11 4 | * @LastEditTime: 2023-08-15 10:47:27 5 | * @LastEditors: 陈宇环 6 | * @Description: 按钮组件 7 | */ 8 | 9 | import { defineComponent, PropType, ref } from 'vue' 10 | import { buttonFace } from './interface/index' 11 | import styles from '@/components/BsButtons/style.module.scss' 12 | import { CustomDynamicComponent } from '@/components/CustomDynamicComponent' 13 | export default defineComponent({ 14 | name: 'BsButtons', 15 | props: { 16 | buttons: { 17 | type: Array as PropType, 18 | default() { 19 | return [] 20 | }, 21 | }, 22 | }, 23 | setup(props: any) { 24 | const loading = ref(false) 25 | const dynamicComponent = new CustomDynamicComponent() 26 | const { dynamicButton, dynamicPopconfirm } = dynamicComponent 27 | return () => { 28 | const buttonDom = (button: buttonFace) => { 29 | return ( 30 | { 37 | loading.value = true 38 | !button.confirmConfig && button.click && (await button.click()) 39 | loading.value = false 40 | }} 41 | > 42 | {button.text ?? '文案'} 43 | 44 | ) 45 | } 46 | return ( 47 |
48 | {props.buttons.map((button: buttonFace) => { 49 | if (button.show === false) { 50 | return null 51 | } 52 | if (button.confirmConfig && !button.disabled) { 53 | return ( 54 | { 65 | if (button?.confirmConfig?.confirm) { 66 | button?.confirmConfig?.confirm() 67 | } else if (button.click) { 68 | button?.click() 69 | } 70 | }} 71 | onCancel={() => { 72 | button?.confirmConfig?.cancel && 73 | button?.confirmConfig?.cancel() 74 | }} 75 | v-slots={{ 76 | reference: () => { 77 | // ele 特有属性 78 | return buttonDom(button) 79 | }, 80 | default: () => { 81 | // ant-design-vue特有属性 82 | return buttonDom(button) 83 | }, 84 | }} 85 | > 86 | ) 87 | } 88 | return buttonDom(button) 89 | })} 90 |
91 | ) 92 | } 93 | }, 94 | }) 95 | 96 | export * from './interface/index' 97 | -------------------------------------------------------------------------------- /src/components/BsButtons/interface/index.ts: -------------------------------------------------------------------------------- 1 | import { ButtonType } from 'element-plus' 2 | 3 | /** 按钮配置对象定义 */ 4 | export interface buttonFace { 5 | /** 是否展示 */ 6 | show?: boolean, 7 | /** 按钮文案 */ 8 | text?: string, 9 | /** 是否禁用 */ 10 | disabled?: boolean, 11 | /** 按钮type */ 12 | type?: ButtonType, 13 | /** 按钮大小 */ 14 | size?: import('element-plus/es/utils').EpPropMergeType, 15 | /** 点击事件 */ 16 | click?: () => void, 17 | /** 二次确认弹窗配置 */ 18 | confirmConfig?: { 19 | /** 二次确认标题 */ 20 | title: string, 21 | /** 二次确认-确认事件 */ 22 | confirm?: () => void, 23 | /** 二次确认-取消事件 */ 24 | cancel?: () => void, 25 | /** el-popconfirm二次确认弹窗原生属性兼容 */ 26 | nativeProps?: { 27 | [key: string]: any 28 | } 29 | } 30 | /** ui框架原生属性 */ 31 | nativeProps?: { 32 | [key: string]: any 33 | } 34 | } -------------------------------------------------------------------------------- /src/components/BsButtons/style.module.scss: -------------------------------------------------------------------------------- 1 | .BsButtons { 2 | 3 | } -------------------------------------------------------------------------------- /src/components/BsDialog/BsFormDialog/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 陈宇环 3 | * @Date: 2023-02-06 14:35:55 4 | * @LastEditTime: 2023-09-01 11:37:27 5 | * @LastEditors: 陈宇环 6 | * @Description: 表单类-弹窗 7 | */ 8 | 9 | import { defineComponent, ref, reactive } from 'vue' 10 | import { dialogFormFace, dialogFormShowConfigFace } from '../interface/index' 11 | import BsDialog from '../index' 12 | import BsForm, { columnsBase, formConfig } from '@/components/BsForm' 13 | import merge from 'lodash/merge' 14 | export default defineComponent({ 15 | setup(props: any, { expose }) { 16 | const BsDialogRef = ref() 17 | const BsFormRef = ref() 18 | const formDiologDefultConfig:dialogFormFace = reactive({ 19 | title: '', // dialog标题 20 | width: '800px', // dialog宽度 21 | confirmText: '确认', // 确认按钮文案 22 | cancelText: '关闭', // 取消按钮文案 23 | formConfig: { 24 | columns: [], // 表单项配置 25 | colNum: 24, 26 | labelWidth: '100px', // label宽度 27 | notOpBtn: true, // 不需要(搜索,重置,导出)操作按钮 28 | }, 29 | }) 30 | const formConfig = ref({ 31 | columns: [], 32 | }) 33 | const form = ref() 34 | const show = ({ config, formInitValue }: dialogFormShowConfigFace) => { 35 | form.value = formInitValue ? formInitValue : {} 36 | 37 | formConfig.value = merge({}, formDiologDefultConfig.formConfig, config.formConfig) 38 | 39 | const formDiologConfig:dialogFormFace = merge({}, formDiologDefultConfig, { 40 | ...config, 41 | confirm: config?.confirm ? async() => { 42 | const verify = await BsFormRef.value.validate() 43 | if (!verify) { 44 | return false 45 | } 46 | return config.confirm && await config.confirm(form.value) !== false 47 | } : undefined, 48 | render: () => { 49 | return ( 50 | <> 51 | 57 | 58 | ) 59 | }, 60 | }) 61 | BsDialogRef.value?.show(formDiologConfig) 62 | // 解决编辑之后在新增数据为空时,检验数据仍然爆红 63 | setTimeout(() => { 64 | BsFormRef.value?.clearValidate() 65 | }) 66 | } 67 | 68 | const setFormFieldsValue = (name:string, val:any) => { 69 | setTimeout(() => { 70 | form.value[name] = val 71 | }) 72 | } 73 | 74 | const getFormFieldsValue = (name?:string) => { 75 | if (!name) { 76 | return form.value 77 | } 78 | return form.value[name] 79 | } 80 | 81 | // 修改columns-将columns中prop为propKey的对象的feildKey字段值设置成value eg(name, required, false) 将名称项设置成非必填 82 | const setFormColumnsByProp = (propKey: string, feildKey: keyof columnsBase, value: any):void => { 83 | const index = formConfig.value.columns.findIndex((item:columnsBase) => item.prop === propKey) 84 | if (index >= 0) { 85 | (formConfig.value.columns[index] as any)[feildKey] = value 86 | } 87 | } 88 | 89 | expose({ BsFormRef, show, setFormFieldsValue, getFormFieldsValue, setFormColumnsByProp }) 90 | 91 | return () => { 92 | return ( 93 |
94 | 97 |
98 | ) 99 | } 100 | }, 101 | }) 102 | 103 | export { dialogFormFace, dialogFormShowConfigFace } 104 | 105 | export type show = ({ config, formInitValue }: dialogFormShowConfigFace) => void -------------------------------------------------------------------------------- /src/components/BsDialog/BsListDialog/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 陈宇环 3 | * @Date: 2023-02-07 15:53:39 4 | * @LastEditTime: 2023-09-01 11:40:55 5 | * @LastEditors: 陈宇环 6 | * @Description: 列表类弹窗(可配置搜索条件) 7 | */ 8 | 9 | import { defineComponent, ref, reactive } from 'vue' 10 | import { dialogListFace, dialogListShowConfigFace } from '../interface/index' 11 | import { loadDataFace } from '@/components/BsTable/interface/index' 12 | import BsDialog from '../index' 13 | import BsForm from '@/components/BsForm' 14 | import BsTable from '@/components/BsTable' 15 | import merge from 'lodash/merge' 16 | export default defineComponent({ 17 | setup(props: any, { expose }) { 18 | const BsDialogRef = ref() 19 | const BsFormRef = ref() 20 | const listDiologDefultConfig:dialogListFace = reactive({ 21 | title: 'form Dialog标题', // dialog标题 22 | width: '800px', // dialog宽度 23 | cancelText: '关闭', // 取消按钮文案 24 | searchConfig: { 25 | columns: [], // 表单项配置 26 | colNum: 6, 27 | labelWidth: '100px', // label宽度 28 | }, 29 | listConfig: { 30 | columns: [], // table列配置 31 | loadData: async() => { 32 | return new Promise(async(resolve) => { 33 | resolve({ 34 | success: true, 35 | list: [], 36 | total: 0, 37 | }) 38 | }) 39 | }, // 加载函数配置 40 | tableConfig: { 41 | ifInitLoadData: true, // table默认初始化加载 42 | }, // 弹窗里table配置 43 | pagingConfig: { 44 | open: true, // 是否需要分页 45 | pageIndex: 1, // 默认pageIndex 46 | pageSize: 10, // 默认pageSize 47 | }, // 分页配置 48 | }, 49 | }) 50 | const BsTableRef = ref() 51 | 52 | const searchFn = () => { 53 | BsTableRef.value?.getList({ 54 | pageIndex: 1, 55 | }) 56 | } 57 | 58 | const searchForm:{[key: string]: any} = ref({}) 59 | const show = async({ config, formInitValue }: dialogListShowConfigFace) => { 60 | searchForm.value = formInitValue ? formInitValue : {} 61 | // 深度merge eg:{a:{b:1}},{a:{c:2}}=>{a:{b:1,c:2}} 62 | const mergeConfig:dialogListFace = merge({}, listDiologDefultConfig, config, { 63 | listConfig: { 64 | tableConfig: { 65 | ifInitLoadData: false, // dialog里的table默认都不初始化加载,需要在show方法中判断传入的config?.listConfig?.tableConfig?.ifInitLoadData来确认是否加载 66 | }, 67 | }, 68 | }) 69 | 70 | // 特殊处理是否需要初始加载,解决第二次打开不会加载数据问题 71 | if (config?.listConfig?.tableConfig?.ifInitLoadData !== false) { 72 | setTimeout(async() => { 73 | const verify = await BsFormRef.value.validate() 74 | if (!verify) { 75 | return 76 | } 77 | searchFn() 78 | }) 79 | } 80 | 81 | const listLoadData:loadDataFace = async({ pageIndex, pageSize }) => { 82 | mergeConfig.searchConfig && (mergeConfig.searchConfig.loading = true) 83 | const res = await mergeConfig.listConfig?.loadData({ 84 | pageIndex, 85 | pageSize, 86 | searchForm: searchForm.value, 87 | }) 88 | mergeConfig.searchConfig && (mergeConfig.searchConfig.loading = false) 89 | return res 90 | } 91 | 92 | const listDiologConfig:dialogListFace = merge({}, mergeConfig, { 93 | // 通过合并之后的conifg来构建render函数 94 | render: () => { 95 | return ( 96 | <> 97 | {mergeConfig?.searchConfig?.columns && { 103 | searchFn() 104 | }} 105 | >} 106 | { 107 | mergeConfig.actionsRender &&
108 | {mergeConfig.actionsRender()} 109 |
110 | } 111 | 119 | 120 | ) 121 | }, 122 | }) 123 | BsDialogRef.value.show(listDiologConfig) 124 | } 125 | 126 | const setForm = (key: string, value: any) => { 127 | setTimeout(() => { 128 | searchForm.value[key] = value 129 | }) 130 | } 131 | 132 | const getForm = (key: string) => { 133 | if (!key) { 134 | return searchForm.value 135 | } 136 | return searchForm.value[key] 137 | } 138 | 139 | const getList = ({ pageIndex, pageSize }: { pageIndex?: number, pageSize?: number } = {}) => { 140 | BsTableRef.value.getList(pageIndex, pageSize) 141 | } 142 | 143 | expose({ BsFormRef, BsTableRef, show, setForm, getForm, getList }) 144 | 145 | return () => { 146 | return ( 147 |
148 | 151 |
152 | ) 153 | } 154 | }, 155 | }) 156 | 157 | export { dialogListFace, dialogListShowConfigFace } 158 | 159 | /* 弹窗显示函数 */ 160 | export type show = ({ config, formInitValue }: dialogListShowConfigFace) => void -------------------------------------------------------------------------------- /src/components/BsDialog/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 陈宇环 3 | * @Date: 2023-01-16 10:34:55 4 | * @LastEditTime: 2023-09-01 11:48:34 5 | * @LastEditors: 陈宇环 6 | * @Description: 基础dialog组件 7 | */ 8 | 9 | import { defineComponent, ref, reactive, nextTick } from 'vue' 10 | import { dialogFace } from './interface/index' 11 | import { CustomDynamicComponent } from '../CustomDynamicComponent' 12 | import merge from 'lodash/merge' 13 | 14 | export default defineComponent({ 15 | setup(props: any, { expose }) { 16 | const dialogFormVisible = ref(false) 17 | const loading = ref(false) 18 | 19 | const dialogDefultConfig = reactive({ 20 | title: '', 21 | width: '600px', 22 | confirmText: '确认', 23 | cancelText: '关闭', 24 | showFooter: true, 25 | }) 26 | 27 | const dialogConfig = ref({ 28 | title: '', 29 | }) 30 | 31 | const show:(config: dialogFace) => void = async(config) => { 32 | dialogConfig.value = merge({}, dialogDefultConfig, config) 33 | loading.value = false 34 | dialogFormVisible.value = true 35 | await nextTick() 36 | } 37 | 38 | expose({ show } as {show: (config: dialogFace) => void}) 39 | 40 | return () => { 41 | const dynamicComponent = new CustomDynamicComponent() 42 | const { 43 | dynamicDialog, 44 | } = dynamicComponent 45 | let footer = null 46 | if (dialogConfig.value.showFooter) { 47 | footer = () => { 48 | return ( 49 | <> 50 | { 51 | loading.value = true 52 | if (dialogConfig.value.cancel) { 53 | dialogConfig.value.cancel && await dialogConfig.value.cancel() !== false && (dialogFormVisible.value = false) 54 | } else { 55 | dialogFormVisible.value = false 56 | } 57 | loading.value = false 58 | }}>{dialogConfig.value.cancelText} 59 | { 60 | dialogConfig.value.confirm && { 61 | loading.value = true 62 | try { 63 | dialogConfig.value.confirm && await dialogConfig.value.confirm() !== false && (dialogFormVisible.value = false) 64 | } catch (error) { 65 | loading.value = false 66 | } 67 | loading.value = false 68 | }}>{dialogConfig.value.confirmText} 69 | } 70 | 71 | ) 72 | } 73 | if (dialogConfig.value.footerRender) { 74 | footer = () => { 75 | return dialogConfig.value.footerRender && dialogConfig.value.footerRender(() => { 76 | dialogFormVisible.value = false 77 | }) 78 | } 79 | } 80 | } 81 | 82 | return
83 | { 89 | dialogConfig.value.nativeProps?.onClose ?? dialogConfig.value.nativeProps?.onClose() 90 | // loading.value = true 91 | // if (dialogConfig.cancel) { 92 | // dialogConfig.cancel && await dialogConfig.cancel() !== false && (dialogFormVisible.value = false) 93 | // } else { 94 | dialogFormVisible.value = false 95 | // } 96 | // loading.value = false 97 | }} 98 | v-slots={{ 99 | default: () => { 100 | return <> 101 | { 102 | dialogConfig.value.render && dialogConfig.value.render() 103 | } 104 | 105 | }, 106 | header: () => { 107 | if (dialogConfig.value.headerRender) { 108 | return dialogConfig.value.headerRender() 109 | } else { 110 | return dialogConfig.value.title 111 | } 112 | }, 113 | footer, 114 | }} 115 | > 116 | 117 |
118 | } 119 | }, 120 | }) 121 | 122 | export { dialogFace } 123 | 124 | /** dialog组件展示方法方法 */ 125 | export type show = (config: dialogFace) => void -------------------------------------------------------------------------------- /src/components/BsDialog/interface/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 陈宇环 3 | * @Date: 2023-01-16 11:01:19 4 | * @LastEditTime: 2023-09-01 11:46:39 5 | * @LastEditors: 陈宇环 6 | * @Description: 弹窗相关接口定义 7 | */ 8 | import { formConfig } from '@/components/BsForm/interface/index' 9 | import { tableConfigFace, pagingConfigFace, columnsConfigFace, resultInt } from '@/components/BsTable/interface/index' 10 | 11 | /** 弹窗配置 */ 12 | export interface dialogFace { 13 | /** dialog标题 */ 14 | title?: string 15 | /** dialog宽度 */ 16 | width?: string 17 | /** 确认按钮文案 */ 18 | confirmText?: string 19 | /** 取消按钮文案 */ 20 | cancelText?: string 21 | /** 确认按钮回调函数,不传则不显示确认按钮 */ 22 | confirm?: (form?: any) => Promise 23 | /** 取消按钮回调函数 */ 24 | cancel?: (form?: any) => any 25 | /** dialog内容render函数 */ 26 | render?: () => any 27 | /** 是否需要底部按钮 */ 28 | showFooter?: boolean 29 | /** dialog底部render函数 */ 30 | footerRender?: (close:()=>void) => any 31 | /** dialog头部render函数 */ 32 | headerRender?: () => any 33 | /** ui框架原生属性 */ 34 | nativeProps?: { 35 | [key: string]: any 36 | } 37 | } 38 | 39 | /** 表单类弹窗配置 */ 40 | export interface dialogFormFace extends dialogFace { 41 | /** 弹窗里表单配置 */ 42 | formConfig: formConfig 43 | } 44 | 45 | /** 表单弹窗 show方法参数 */ 46 | export interface dialogFormShowConfigFace { 47 | /** 表单弹窗配置 */ 48 | config: dialogFormFace, 49 | /** 表单初始值 */ 50 | formInitValue?: {[key: string]: any} 51 | } 52 | 53 | /** 列表类弹窗 */ 54 | export interface dialogListFace extends dialogFace { 55 | /** 搜索条件配置 */ 56 | searchConfig?: formConfig 57 | /** table上方操作按钮区域render函数 */ 58 | actionsRender?: () => any 59 | /** 列表区域配置 */ 60 | listConfig: { 61 | /** 列配置 */ 62 | columns: columnsConfigFace 63 | /** 列表加载函数配置 */ 64 | loadData: listConfigLoadDataFace 65 | /** 弹窗里table配置 */ 66 | tableConfig?: tableConfigFace 67 | /** 分页配置 */ 68 | pagingConfig?: pagingConfigFace 69 | } 70 | } 71 | 72 | /** 列表弹窗 show方法参数 */ 73 | export interface dialogListShowConfigFace { 74 | /** 列表弹窗配置 */ 75 | config: dialogListFace, 76 | /** 表单初始值 */ 77 | formInitValue?: {[key: string]: any} 78 | } 79 | 80 | /** 列表加载函数类型 */ 81 | export type listConfigLoadDataFace = ({ pageIndex, pageSize, searchForm }: { pageIndex: number, pageSize: number, searchForm: any }) => Promise 82 | 83 | -------------------------------------------------------------------------------- /src/components/BsEditTable/BsEditTableItem.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 陈宇环 3 | * @Date: 2022-04-08 13:49:50 4 | * @LastEditTime: 2023-08-16 17:21:13 5 | * @LastEditors: 陈宇环 6 | * @Description: 7 | */ 8 | import { defineComponent, toRefs, PropType } from 'vue' 9 | import BsEditTableItem from './BsEditTableItem' 10 | import { editTableColumnsItemConfig, editTableConfigFace } from './interface/index' 11 | import { CustomDynamicComponent } from '../CustomDynamicComponent' 12 | import { contentRender } from './toolFn' 13 | export default defineComponent({ 14 | name: 'BsEditTableItem', 15 | components: { }, 16 | props: { 17 | itemData: { 18 | type: Object as PropType, 19 | default() { 20 | return { 21 | prop: 'prop', 22 | label: 'label', 23 | } 24 | }, 25 | }, 26 | cloneTableConfig: { 27 | type: Object as PropType, 28 | default() { 29 | return {} 30 | }, 31 | }, 32 | }, 33 | emits: ['change'], 34 | setup(props:any, { emit }) { 35 | const { itemData, cloneTableConfig } = toRefs<{itemData: editTableColumnsItemConfig, cloneTableConfig: editTableConfigFace}>(props) 36 | const dynamicComponent = new CustomDynamicComponent() 37 | const { dynamicTableColumn } = dynamicComponent 38 | // 多级头递归 39 | const childrenDom = () => { 40 | return itemData.value.children && itemData.value.children.length > 0 41 | ? itemData.value.children.map((item:any, index:any) => ( 42 | 46 | )) 47 | : null 48 | } 49 | const emitChange = (scope: any) => { 50 | emit('change', scope) 51 | } 52 | return () => { 53 | // 序号 54 | if (itemData.value.type && itemData.value.type === 'index') { 55 | return 63 | } 64 | // const itemDataProps: columnsItemConfig = _.cloneDeep(itemData.value) 65 | // 解决element-ui报错问题 66 | // itemData.value.children = undefined 67 | return ( 68 | { 78 | return <> 79 | {contentRender(cloneTableConfig.value, itemData.value, scope, () => { 80 | emitChange(scope) 81 | })} 82 | {/* 多级头部 */} 83 | {childrenDom()} 84 | 85 | }, 86 | }} 87 | > 88 | ) 89 | } 90 | }, 91 | }) 92 | -------------------------------------------------------------------------------- /src/components/BsEditTable/interface/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 陈宇环 3 | * @Date: 2023-08-03 10:56:12 4 | * @LastEditTime: 2023-08-28 16:05:48 5 | * @LastEditors: 陈宇环 6 | * @Description: table+paging 接口定义 7 | */ 8 | 9 | import type { columnsBase } from '../../BsForm/interface/index' 10 | import type { tableConfigFace, columnsItemConfig } from '../../BsTable/interface/index' 11 | 12 | /** 编辑table配置参数 */ 13 | export interface editTableConfigFace extends tableConfigFace { 14 | /** 是否编辑状态 */ 15 | editing?: boolean, 16 | /** 行编辑状态对应的key */ 17 | rowEditingKey?: string, 18 | } 19 | 20 | // 将columnsBase联合类型中的prop属性去掉 21 | type formConfigType = T extends U ? string : Omit 22 | 23 | export type widgetConfigFace = formConfigType & { 24 | widgetConfigDynamicFn?: (scope?: any) => Partial 25 | } 26 | 27 | /** 编辑table列配置 */ 28 | export interface editTableColumnsItemConfig extends columnsItemConfig { 29 | /** 范围选择器结束值的key */ 30 | propEnd?: string 31 | /** 当前列是否正在编辑状态 */ 32 | editing?: boolean, 33 | /** 编辑状态下表单项配置 */ 34 | widgetConfig?: widgetConfigFace, 35 | } 36 | 37 | /** 编辑table列配置项item */ 38 | export type editTableColumnsConfigFace = editTableColumnsItemConfig[] -------------------------------------------------------------------------------- /src/components/BsEditTable/style.module.scss: -------------------------------------------------------------------------------- 1 | 2 | 3 | .BsEditTable { 4 | width: 100%; 5 | // height: 100%; 6 | display: flex; 7 | flex-direction: column; 8 | justify-content: space-between; 9 | background-color: #fff; 10 | // padding: 0 15px; 11 | border-radius: 3px; 12 | .table { 13 | flex: 1; 14 | :global(.el-radio__label), :global(.ep-radio__label) { 15 | display: none; 16 | } 17 | } 18 | :global(.el-form-item), :global(.ep-form-item), :global(.ant-form-item) { 19 | margin-bottom: 0; 20 | } 21 | :global(.el-form-item__content), :global(.ep-form-item__content) { 22 | flex-wrap: inherit; 23 | } 24 | :global(.ant-form-item-control) { 25 | position: relative; 26 | } 27 | :global(.ant-form-item-explain-connected) { 28 | position: absolute; 29 | top: 100%; 30 | left: 0; 31 | white-space: nowrap; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/components/BsEditTable/toolFn.tsx: -------------------------------------------------------------------------------- 1 | import { commonRules, rulesIn } from '@/utils/validator' 2 | import { widgetConfigFace, editTableConfigFace, editTableColumnsItemConfig } from './interface/index' 3 | import { inlayRuleType } from '@/components/BsForm/interface/index' 4 | // 导入所有自定义form控件组件 5 | import * as widget from '@/components/BsForm/components/index' 6 | import styles from './style.module.scss' 7 | import { CustomDynamicComponent } from '../CustomDynamicComponent' 8 | // 正则验证 9 | const asyncValidator = (val: string | number | any[], type: keyof rulesIn) => val ? commonRules[type][0].test(val) : true 10 | // 错误消息打印 11 | const asyncMessage = (type: keyof rulesIn) => commonRules[type][1] 12 | 13 | // 根据table编辑项配置来获取单个项目的校验规则 14 | export const getItemRules = (widgetConfig: widgetConfigFace) => { 15 | return [ 16 | { 17 | required: widgetConfig?.required, 18 | message: `${ 19 | widgetConfig?.type && ['input', 'textarea', 'number', 'numberRange'].includes(widgetConfig?.type) ? '请输入' : '请选择' 20 | }`, 21 | trigger: 'change', 22 | }, 23 | ...(widgetConfig?.inlayRules ? widgetConfig?.inlayRules?.map((item: inlayRuleType) => { 24 | return { 25 | validator: (rule: any, value: any) => { 26 | if (!asyncValidator(value, item.validatorName)) { 27 | return Promise.reject(item.message ?? asyncMessage(item.validatorName)) 28 | } 29 | return Promise.resolve() 30 | }, 31 | trigger: item.trigger ?? 'change', 32 | } 33 | }) : []), 34 | ...(widgetConfig?.rules ? widgetConfig?.rules : []), 35 | ] 36 | } 37 | 38 | /** 39 | * @description: 单元格渲染函数 40 | * @param {editTableConfigFace} cloneTableConfig 表格配置 41 | * @param {editTableColumnsItemConfig} columnConfig 当前列配置 42 | * @param {any} scope 当前行数组 ps: ele为原生插槽scope数据,ant是通过手动拼凑的 43 | * @param {function} emitChange // 编辑控件变化时会调用这个方法 44 | * @return {*} 45 | */ 46 | export const contentRender = (cloneTableConfig: editTableConfigFace, columnConfig: editTableColumnsItemConfig, scope: any, emitChange:()=>void) => { 47 | const dynamicComponent = new CustomDynamicComponent() 48 | const { dynamicFormItem } = dynamicComponent 49 | // element-plus 默认$index === -1 这里需要排除一下 50 | if (scope.$index === -1) { 51 | return 52 | } 53 | // 列编辑 整表编辑!==关闭状态 && 列编辑开启 && 列存在formconfig 54 | const colEditing = cloneTableConfig.editing !== false && columnConfig.editing 55 | // 行编辑 整表编辑!==关闭状态 && 行编辑开启 && 列存在formconfig 56 | const rowEditing = cloneTableConfig.editing !== false && scope.row[cloneTableConfig?.rowEditingKey ?? 'editing'] 57 | // 整表编辑 整表编辑 && 当前列编辑!==关闭状态 && 行编辑!==关闭状态 && 存在配置 58 | const overallEditing = cloneTableConfig.editing && columnConfig.editing !== false && scope.row[cloneTableConfig?.rowEditingKey ?? 'editing'] !== false 59 | if ((colEditing || overallEditing || rowEditing) && columnConfig.widgetConfig) { // 渲染编辑组件 60 | const componentInstance = widget.getComponentByType(columnConfig.widgetConfig.type) 61 | return { 72 | return
73 | 74 |
75 | }, 76 | }} 77 | > 78 | { 85 | columnConfig.widgetConfig?.change && columnConfig.widgetConfig.change(scope) 86 | emitChange() 87 | }} 88 | /> 89 |
90 | } 91 | if (columnConfig.render) { 92 | return typeof columnConfig.render === 'function' ? columnConfig.render(scope) : columnConfig.render 93 | } 94 | if (columnConfig.propEnd) { 95 | return scope.row[(columnConfig as {prop: string}).prop] + ' - ' + scope.row[(columnConfig as {propEnd: string}).propEnd] 96 | } 97 | return scope.row[(columnConfig as {prop: string}).prop] 98 | } 99 | 100 | // 获取树所有叶子节点 101 | export function getAllLeaf(data: any) { 102 | const result:any[] = [] 103 | function getLeaf(data: any) { 104 | data.forEach((item: any) => { 105 | if (!item.children) { 106 | result.push(item) 107 | } else { 108 | getLeaf(item.children) 109 | } 110 | }) 111 | } 112 | getLeaf(data) 113 | return result 114 | } -------------------------------------------------------------------------------- /src/components/BsForm/components/BsCascader.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 陈宇环 3 | * @Date: 2022-09-07 16:37:21 4 | * @LastEditTime: 2023-09-12 20:04:05 5 | * @LastEditors: 陈宇环 6 | * @Description: 7 | */ 8 | import { defineComponent, watch, ref, PropType } from 'vue' 9 | import * as utils from '@/utils/common' 10 | import type { cascaderProps } from '../interface/index' 11 | import styles from '@/components/BsForm/style.module.scss' 12 | import { CustomDynamicComponent } from '@/components/CustomDynamicComponent' 13 | import { textModeFilter } from '../toolFn' 14 | import merge from 'lodash/merge' 15 | 16 | export default defineComponent({ 17 | name: 'BsCascader', 18 | props: { 19 | modelValue: { 20 | type: [Number, String, Array, Object, Boolean], 21 | default: '', 22 | }, 23 | config: { 24 | type: Object as PropType, 25 | default() { 26 | return {} 27 | }, 28 | }, 29 | textMode: { 30 | type: Boolean, 31 | default: false, 32 | }, 33 | }, 34 | emits: ['update:modelValue', 'update:value', 'change'], 35 | setup(props: any, { emit }) { 36 | const options = ref<{[label: string]: any}[]>([]) 37 | const optionsLoading = ref(false) 38 | watch(() => props.config.options, async() => { 39 | // 获取options下拉选项 40 | if (Array.isArray(props.config.options)) { // 传入对象数组 41 | options.value = props.config.options 42 | } else if (Object.prototype.toString.call(props.config.options) === '[object Object]') { // 字典/接口获取 43 | if (props.config?.options?.type === 'api') { 44 | optionsLoading.value = true 45 | options.value = await props.config.options.getData() 46 | optionsLoading.value = false 47 | } else if (props.config?.options?.type === 'dic') { 48 | options.value = utils.getDicByKey(props.config.options.key) 49 | } 50 | } 51 | }, { immediate: true, deep: true }) 52 | 53 | /** 54 | * @description: 获取选中得item 55 | * @param {*} value 当前选择中得value ps: 56 | * 单选:'changsha' || ['hunan','changsha'](开启emitPath时) 57 | * 多选:['changsha','yiyang'] || [['hunan','changsha'], ['hunan', 'yiyang']](开启emitPath时) 58 | * @return any 选中得item 59 | */ 60 | const getOption = (value: any) => { 61 | let curItem: any 62 | let valueString: any 63 | const valueIsArray = Array.isArray(value) 64 | utils.treeForeach(options.value, (node) => { 65 | if (props.config.multiple) { 66 | try { 67 | valueString = value && Array.isArray(value) ? value.map((item: any) => Array.isArray(item) ? item[item.length - 1] : item) : [] 68 | if (valueString.includes(node[props?.config?.valueKey ?? 'value'])) { 69 | if (!Array.isArray(curItem)) { 70 | curItem = [] 71 | } 72 | curItem.push(node) 73 | } 74 | } catch (error) { 75 | curItem = [] 76 | console.log(error) 77 | } 78 | } else { 79 | try { 80 | if (valueIsArray) { // emitPath 模式 81 | valueString = value[value.length - 1] 82 | } 83 | if (node[props?.config?.valueKey ?? 'value'] === valueString) { 84 | curItem = node 85 | } 86 | } catch (error) { 87 | curItem = {} 88 | console.log(error) 89 | } 90 | 91 | } 92 | }, props.config.childrenKey ?? 'children') 93 | return curItem 94 | } 95 | 96 | const handleChange = (value: any) => { 97 | emit('update:modelValue', value) 98 | emit('update:value', value) 99 | emit('change', { 100 | prop: props.config?.prop ?? '', 101 | value, 102 | options: options.value, 103 | curItem: getOption(value), 104 | }) 105 | } 106 | 107 | const getText = () => { 108 | if (Array.isArray(getOption(props.modelValue))) { 109 | return getOption(props.modelValue)?.map((item: any) => item[props.config.labelKey ?? 'label']).join('、') 110 | } 111 | return getOption(props.modelValue)?.[props.config.labelKey ?? 'label'] 112 | } 113 | 114 | return () => { 115 | const dynamicComponent = new CustomDynamicComponent() 116 | const { dynamicCascader } = dynamicComponent 117 | return
118 | {textModeFilter(props.textMode, getText() ?? '', props.config.textModeRender && props.config.textModeRender({ 119 | value: props.modelValue, 120 | options: options.value, 121 | curItem: getOption(props.modelValue), 122 | }), { 154 | return props.config.format && props.config.format(node, data) 155 | }, 156 | } : {}} 157 | /** ele 特有属性-end */ 158 | 159 | {...props.config.nativeProps} 160 | props={merge({}, { 161 | emitPath: (props.config.emitPath === true), // ===true时才会返回true 162 | label: props.config.labelKey ?? 'label', 163 | value: props.config.valueKey ?? 'value', 164 | children: props.config.childrenKey ?? 'children', 165 | multiple: props.config.multiple === true, 166 | }, props.config?.nativeProps?.props)} 167 | 168 | onChange={handleChange} 169 | > 170 | , 171 | )} 172 |
173 | } 174 | }, 175 | }) 176 | 177 | export { cascaderProps } -------------------------------------------------------------------------------- /src/components/BsForm/components/BsCheckbox.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 陈宇环 3 | * @Date: 2022-12-20 09:56:21 4 | * @LastEditTime: 2023-09-15 11:08:08 5 | * @LastEditors: 陈宇环 6 | * @Description: 7 | */ 8 | import { defineComponent, watch, ref, PropType } from 'vue' 9 | import * as utils from '@/utils/common' 10 | import type { checkboxProps } from '../interface/index' 11 | import styles from '@/components/BsForm/style.module.scss' 12 | import { CustomDynamicComponent } from '@/components/CustomDynamicComponent' 13 | import { textModeFilter, getOptionsLabel } from '../toolFn' 14 | 15 | export default defineComponent({ 16 | name: 'BsCheckbox', 17 | props: { 18 | modelValue: { 19 | type: Array, 20 | default() { 21 | return [] 22 | }, 23 | }, 24 | config: { 25 | type: Object as PropType, 26 | default() { 27 | return {} 28 | }, 29 | }, 30 | textMode: { 31 | type: Boolean, 32 | default: false, 33 | }, 34 | }, 35 | emits: ['update:modelValue', 'update:value', 'change'], 36 | setup(props: any, { emit }) { 37 | const options = ref([]) 38 | const optionsLoading = ref(false) 39 | watch(() => props.config.options, async() => { 40 | // 获取options下拉选项 41 | if (Array.isArray(props.config.options)) { // 传入对象数组 42 | options.value = props.config.options 43 | } else if (Object.prototype.toString.call(props.config.options) === '[object Object]') { // 字典/接口获取 44 | if (props.config.options.type === 'api') { 45 | optionsLoading.value = true 46 | options.value = await props.config.options.getData() 47 | optionsLoading.value = false 48 | } else if (props.config.options.type === 'dic') { 49 | options.value = utils.getDicByKey(props.config.options.key) 50 | } 51 | } 52 | // 兼容改变 53 | options.value = options?.value?.map((v: any) => { 54 | return { 55 | ...v, 56 | label: v[props.config.labelKey || 'label'], 57 | value: v[props.config.valueKey || 'value'], 58 | } 59 | }) ?? [] 60 | 61 | }, { immediate: true, deep: true }) 62 | 63 | /** 64 | * @description: 获取选中得item 65 | * @param {*} value 当前选择中得value 66 | * @return any 选中得item 67 | */ 68 | const getOption = (value: any) => { 69 | try { 70 | const optionArr = options.value.filter((option: any) => value?.includes(option.value)) ?? [] 71 | return optionArr 72 | } catch (error) { 73 | console.log(error) 74 | return [] 75 | } 76 | } 77 | 78 | function updateValue(value: any): void { 79 | emit('update:modelValue', value) 80 | emit('update:value', value) 81 | emit('change', { 82 | prop: props.config?.prop ?? '', 83 | value, 84 | options, 85 | curItem: getOption(value), 86 | }) 87 | } 88 | 89 | return () => { 90 | const dynamicComponent = new CustomDynamicComponent() 91 | const { dynamicCheckBoxGroup, dynamicCheckBox, dynamicCheckBoxButton } = dynamicComponent 92 | // dynamicCheckBoxButton 只有element-plus有这个组件 93 | const componentInstance = props.config.showType === 'button' && CustomDynamicComponent.language === CustomDynamicComponent.eleLanguage ? dynamicCheckBoxButton : dynamicCheckBox 94 | return
95 | {textModeFilter(props.textMode, getOptionsLabel(getOption(props.modelValue)) ?? '', props.config.textModeRender && props.config.textModeRender({ 96 | value: props.modelValue, 97 | options: options.value, 98 | curItem: getOption(props.modelValue), 99 | }), 100 | 115 | { 116 | /** 只有element-plus使用以下逻辑 */ 117 | CustomDynamicComponent.language === CustomDynamicComponent.eleLanguage && options.value && Array.isArray(options.value) && options.value.map((item: any, index: number) => { 118 | return { 125 | return props.config.format(item) 126 | }, 127 | } : {}} 128 | > 129 | { item.label } 130 | 131 | }) 132 | } 133 | , 134 | )} 135 |
136 | } 137 | }, 138 | }) 139 | 140 | export { checkboxProps } -------------------------------------------------------------------------------- /src/components/BsForm/components/BsCollapse.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: chenql 3 | * @Date: 2023-04-26 10:19:48 4 | * @LastEditors: 陈宇环 5 | * @LastEditTime: 2023-09-07 10:20:46 6 | * @Descripttion: 表单手风琴 7 | */ 8 | import { defineComponent, PropType, ref } from 'vue' 9 | import type { collapseProps } from '../interface' 10 | import styles from '@/components/BsForm/style.module.scss' 11 | import { CustomDynamicComponent } from '@/components/CustomDynamicComponent' 12 | 13 | export default defineComponent({ 14 | name: 'BsCollapse', 15 | props: { 16 | modelValue: { 17 | type: [Number, String, Array, Object, Boolean], 18 | default: undefined, 19 | }, 20 | config: { 21 | type: Object as PropType, 22 | default() { 23 | return {} 24 | }, 25 | }, 26 | }, 27 | setup(props: any) { 28 | const { dynamicCollapse, dynamicCollapseItem } = new CustomDynamicComponent() 29 | const activeKey = ref(props.modelValue ?? 0) 30 | return () => { 31 | return ( 32 |
33 | 40 | {props.config.dataConfig?.map((item: any, index: number) => 41 | 47 | { 48 | Array.isArray(item.desc) ? 49 | (item.desc?.map((str: any, index1: number) => 50 |

51 | {str} 52 |

)) : 53 |

54 | {item.desc} 55 |

56 | } 57 |
, 58 | )} 59 |
60 |
61 | ) 62 | } 63 | }, 64 | }) 65 | export { collapseProps } 66 | -------------------------------------------------------------------------------- /src/components/BsForm/components/BsDate.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 陈宇环 3 | * @Date: 2022-12-20 11:33:03 4 | * @LastEditTime: 2023-09-01 11:20:03 5 | * @LastEditors: 陈宇环 6 | * @Description: 7 | */ 8 | import { defineComponent, watch, ref, PropType } from 'vue' 9 | import type { dateProps } from '../interface/index' 10 | import styles from '@/components/BsForm/style.module.scss' 11 | import { CustomDynamicComponent } from '@/components/CustomDynamicComponent' 12 | import dayjs, { Dayjs } from 'dayjs' 13 | import { textModeFilter } from '../toolFn' 14 | 15 | export default defineComponent({ 16 | name: 'BsDate', 17 | props: { 18 | modelValue: { 19 | type: [String, Array], 20 | default: '', 21 | }, 22 | propSecond: { 23 | type: [String], 24 | default: '', 25 | }, 26 | propThird: { 27 | type: [String], 28 | default: '', 29 | }, 30 | config: { 31 | type: Object as PropType, 32 | default() { 33 | return {} 34 | }, 35 | }, 36 | textMode: { 37 | type: Boolean, 38 | default: false, 39 | }, 40 | }, 41 | emits: ['update:modelValue', 'update:value', 'change', 'update:propSecond', 'update:propThird'], 42 | setup(props: any, { emit }) { 43 | function getFormat(type: string, formatType: 'format' | 'valueFormat'): string { 44 | if (['date', 'daterange'].includes(type)) { 45 | return 'YYYY-MM-DD' 46 | } 47 | if (['month', 'monthrange'].includes(type)) { 48 | return 'YYYY-MM' 49 | } 50 | if (type === 'year') { 51 | return 'YYYY' 52 | } 53 | if (type === 'week') { 54 | if (formatType === 'format') { 55 | return '第 ww 周' 56 | } else { 57 | return '' 58 | } 59 | } 60 | if (['datetime', 'datetimerange'].includes(type)) { 61 | return 'YYYY-MM-DD HH:mm:ss' 62 | } 63 | return 'YYYY-MM-DD' 64 | } 65 | const cloneModelValue = ref(dayjs()) 66 | watch(() => props.modelValue, () => { 67 | cloneModelValue.value = props.modelValue 68 | }, { immediate: true }) 69 | 70 | // 解决datetime类型,不点击确认按钮无法触发change事件bug 71 | watch(() => cloneModelValue.value, () => { 72 | updateValue(cloneModelValue.value) 73 | }) 74 | 75 | function updateValue(value: Dayjs) { 76 | emit('update:modelValue', value) 77 | emit('update:value', value) 78 | // 当是范围时间选择器时,开始和结束时间处理 79 | if (Array.isArray(value) && value?.length === 2) { 80 | props.config.propSecond && emit('update:propSecond', value[0]) 81 | props.config.propThird && emit('update:propThird', value[1]) 82 | } 83 | // 时间选择器被清空时,重置propSecond和prop2 84 | if (!value) { 85 | props.config.propSecond && emit('update:propSecond', null) 86 | props.config.propThird && emit('update:propThird', null) 87 | } 88 | emit('change', { 89 | prop: props.config?.prop ?? '', 90 | value, 91 | }) 92 | } 93 | 94 | const getText = () => { 95 | if (!cloneModelValue.value) { 96 | return '' 97 | } 98 | if (Array.isArray(cloneModelValue.value)) { 99 | return cloneModelValue.value.map((item: any) => { 100 | if (!item) { 101 | return '-' 102 | } 103 | return dayjs(item).format(getFormat(props.config.type, 'format')) 104 | }).join('~') 105 | } 106 | return dayjs(cloneModelValue.value).format(getFormat(props.config.type, 'format')) 107 | } 108 | 109 | return () => { 110 | const dynamicComponent = new CustomDynamicComponent() 111 | const { dynamicDatePicker, dynamicRangePicker } = dynamicComponent 112 | let dateComp = dynamicDatePicker 113 | // antd 的时间范围组件特殊处理 114 | if (CustomDynamicComponent.language === CustomDynamicComponent.antLanguage && props.config.type?.indexOf('range') > -1) { 115 | dateComp = dynamicRangePicker 116 | } 117 | const getPicker = (type: string) => { 118 | if (CustomDynamicComponent.language === CustomDynamicComponent.antLanguage && props.config.type?.indexOf('range') > -1) { 119 | return props.config.type.replace('range', '') 120 | } 121 | return type 122 | } 123 | return
124 | {textModeFilter(props.textMode, getText() ?? '', props.config.textModeRender && props.config.textModeRender({ 125 | value: cloneModelValue.value, 126 | }), 127 | , 153 | )} 154 |
155 | } 156 | }, 157 | }) 158 | 159 | export { dateProps } 160 | -------------------------------------------------------------------------------- /src/components/BsForm/components/BsDateRange.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: 陈宇环 3 | * @Date: 2022-04-28 15:34:56 4 | * @LastEditTime: 2023-09-01 11:20:21 5 | * @LastEditors: 陈宇环 6 | * @Description: 'yearRange' | 'monthRange' | 'dateRange' | 'datetimeRange'组件 7 | */ 8 | import { defineComponent, watch, ref, PropType } from 'vue' 9 | import type { dateRangeProps } from '../interface/index' 10 | import dayjs from 'dayjs' 11 | import styles from '@/components/BsForm/style.module.scss' 12 | import { CustomDynamicComponent } from '@/components/CustomDynamicComponent' 13 | import { textModeFilter } from '../toolFn' 14 | 15 | export default defineComponent({ 16 | name: 'BsDateRange', 17 | props: { 18 | modelValue: { 19 | type: [String, Number], 20 | default: '', 21 | }, 22 | propEnd: { 23 | type: [String, Number], 24 | default: '', 25 | }, 26 | config: { 27 | type: Object as PropType, 28 | default() { 29 | return {} 30 | }, 31 | }, 32 | textMode: { 33 | type: Boolean, 34 | default: false, 35 | }, 36 | }, 37 | emits: ['update:modelValue', 'update:value', 'update:propEnd', 'change'], 38 | setup(props: any, { emit }) { 39 | 40 | const cloneModelValue = ref('') 41 | watch(() => props.modelValue, () => { 42 | cloneModelValue.value = props.modelValue 43 | }, { immediate: true }) 44 | 45 | // 解决datetime类型,不点击确认按钮无法触发change事件bug 46 | watch(() => cloneModelValue.value, () => { 47 | updateValue(cloneModelValue.value) 48 | }) 49 | 50 | function updateValue(value: number | string) { 51 | emit('update:modelValue', value) 52 | emit('update:value', value) 53 | emit('change', { 54 | type: 'start', 55 | prop: props.config?.prop ?? '', 56 | value, 57 | }) 58 | } 59 | 60 | const clonePropEnd = ref('') 61 | watch(() => props.propEnd, () => { 62 | clonePropEnd.value = props.propEnd 63 | }, { immediate: true }) 64 | // 解决datetime类型,不点击确认按钮无法触发change事件bug 65 | watch(() => clonePropEnd.value, () => { 66 | updateEndValue(clonePropEnd.value) 67 | }) 68 | function updateEndValue(value: number | string) { 69 | emit('update:propEnd', value) 70 | emit('change', { 71 | type: 'end', 72 | prop: props.config?.propEnd ?? '', 73 | value, 74 | }) 75 | } 76 | 77 | function disabledDate(date: any): boolean { 78 | if (clonePropEnd.value) { 79 | // 这里format为了解决element默认08:00:00 80 | return +new Date(dayjs(date).format('YYYY-MM-DD HH:mm:ss')) > +new Date(dayjs(clonePropEnd.value).format('YYYY-MM-DD HH:mm:ss')) 81 | } 82 | return false 83 | } 84 | function disabledDateEnd(date: any): boolean { 85 | if (cloneModelValue.value) { 86 | return +new Date(dayjs(date).format('YYYY-MM-DD HH:mm:ss')) < +new Date(dayjs(cloneModelValue.value).format('YYYY-MM-DD HH:mm:ss')) 87 | } 88 | return false 89 | } 90 | 91 | 92 | function removerRange(type: string): any { 93 | return type?.replace('Range', '') 94 | } 95 | 96 | function getFormat(type: string, formatType: 'format' | 'valueFormat'): string | undefined { 97 | if (removerRange(type) === 'date') { 98 | return 'YYYY-MM-DD' 99 | } 100 | if (removerRange(type) === 'month') { 101 | return 'YYYY-MM' 102 | } 103 | if (removerRange(type) === 'year') { 104 | return 'YYYY' 105 | } 106 | if (removerRange(type) === 'week') { 107 | if (formatType === 'format') { 108 | return '第 ww 周' 109 | } else { 110 | return undefined 111 | } 112 | } 113 | if (removerRange(type) === 'datetime') { 114 | return 'YYYY-MM-DD HH:mm:ss' 115 | } 116 | return 'YYYY-MM-DD' 117 | } 118 | 119 | const getText = () => { 120 | if (!cloneModelValue.value && !clonePropEnd.value) { 121 | return '' 122 | } 123 | const startText = cloneModelValue.value ? dayjs(cloneModelValue.value).format(getFormat(props.config.type, 'format')) : '-' 124 | const endText = clonePropEnd.value ? dayjs(clonePropEnd.value).format(getFormat(props.config.type, 'format')) : '-' 125 | return `${startText}~${endText}` 126 | } 127 | 128 | return () => { 129 | const dynamicComponent = new CustomDynamicComponent() 130 | const { dynamicDatePicker } = dynamicComponent 131 | // ant-design-vue formitem只允许一个form控件 132 | const formItem = CustomDynamicComponent.language === CustomDynamicComponent.antLanguage ? :