├── .eslintrc.js
├── .gitee
├── ISSUE_TEMPLATE.en.md
├── ISSUE_TEMPLATE.md
└── ISSUE_TEMPLATE.zh-TW.md
├── .github
└── ISSUE_TEMPLATE
│ ├── bug_report.yml
│ └── feature_request.yml
├── .gitignore
├── LICENSE
├── README.md
├── gulpfile.js
├── index.ts
├── package.json
├── style.scss
├── tsconfig.json
└── types
└── index.d.ts
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // https://eslint.org/docs/user-guide/configuring
2 |
3 | module.exports = {
4 | root: true,
5 | parser: '@typescript-eslint/parser',
6 | parserOptions: {
7 | ecmaVersion: 6,
8 | sourceType: 'module',
9 | ecmaFeatures: {
10 | impliedStrict: true,
11 | objectLiteralDuplicateProperties: false
12 | }
13 | },
14 | env: {
15 | amd: true,
16 | browser: true,
17 | node: true
18 | },
19 | plugins: [
20 | '@typescript-eslint'
21 | ],
22 | extends: [
23 | 'prettier/@typescript-eslint',
24 | 'standard'
25 | ],
26 | rules: {
27 | 'array-bracket-spacing': ['error', 'never'],
28 | 'no-debugger': ['error'],
29 | 'keyword-spacing': ['error']
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/.gitee/ISSUE_TEMPLATE.en.md:
--------------------------------------------------------------------------------
1 | **(Required) Describe the bug or screenshots:**
2 | ?
3 |
4 | **(Required) Reproduction link:**
5 | ?
6 |
7 | **(Required) Expected behavior:**
8 | ?
9 |
10 | **(Required) Please fill in the version information:**
11 |
12 | - OS: ?
13 | - Browser: ?
14 | - vue: ?
15 | - vxe-table: ?
16 |
--------------------------------------------------------------------------------
/.gitee/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | **(必填)请填写问题描述或截图:**
2 | ?
3 |
4 | **(必填)请填重在线链接:**
5 | ?
6 |
7 | **(必填)请填写期望的结果:**
8 | ?
9 |
10 | **(必填)请填写以下信息:**
11 |
12 | - OS: ?
13 | - Browser: ?
14 | - vue: ?
15 | - vxe-table: ?
16 |
--------------------------------------------------------------------------------
/.gitee/ISSUE_TEMPLATE.zh-TW.md:
--------------------------------------------------------------------------------
1 | **(必填)請填寫問題描述或截圖:**
2 | ?
3 |
4 | **(必填)請填重線上連結:**
5 | ?
6 |
7 | **(必填)請填寫期望的結果:**
8 | ?
9 |
10 | **(必填)請填寫以下資訊:**
11 |
12 | - OS: ?
13 | - Browser: ?
14 | - vue: ?
15 | - vxe-table: ?
16 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.yml:
--------------------------------------------------------------------------------
1 | name: Bug report
2 | description: 反馈问题
3 | labels: bug
4 | body:
5 | - type: input
6 | id: issue_link
7 | attributes:
8 | label: "可复现的链接:"
9 | description: "一个最小化的重现示例能让我们精确地定位问题,从而快速解决问题。如何创建,点击 v3:[codesandbox](https://codesandbox.io/s/vue-template-916h0)、[jsfiddle](https://jsfiddle.net/86p7Ltny/)、[jsrun](https://jsrun.net/vIyKp/edit) 或 v4:[codesandbox](https://codesandbox.io/s/vxe-table-wentiyanshi-forked-54v2j)、[jsfiddle](https://jsfiddle.net/9qoghkbj/)、[jsrun](https://jsrun.net/K5IKp/edit),将代码示例编辑后保存。"
10 | validations:
11 | required: true
12 | - type: textarea
13 | id: issue_describe
14 | attributes:
15 | label: "问题描述与截图:"
16 | validations:
17 | required: true
18 | - type: markdown
19 | attributes:
20 | value: "在发布问题之前,请仔细阅读所填写的步骤,以确保是详细和清晰的。"
21 | - type: input
22 | id: issue_expect
23 | attributes:
24 | label: "期望的结果:"
25 | - type: input
26 | id: issue_os_version
27 | attributes:
28 | label: "操作系统:"
29 | placeholder: "例如:window10"
30 | validations:
31 | required: true
32 | - type: input
33 | id: issue_browser_version
34 | attributes:
35 | label: "浏览器版本:"
36 | placeholder: "例如:chrome 95.0.4638.69"
37 | validations:
38 | required: true
39 | - type: input
40 | id: issue_vue_version
41 | attributes:
42 | label: "vue 版本:"
43 | placeholder: "例如:2.6.0"
44 | validations:
45 | required: true
46 | - type: input
47 | id: issue_vxe_version
48 | attributes:
49 | label: "vxe-table 版本:"
50 | placeholder: "例如:3.4.0"
51 | validations:
52 | required: true
53 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.yml:
--------------------------------------------------------------------------------
1 | name: Feature request
2 | description: 功能需求
3 | labels: enhancement
4 | body:
5 | - type: textarea
6 | id: issue_describe
7 | attributes:
8 | label: "这个需求解决了什么问题:"
9 | validations:
10 | required: true
11 | - type: markdown
12 | attributes:
13 | value: "请先查看[最新文档](https://xuliangzhan_admin.gitee.io/vxe-table/#/table/api),确定该功能是否已有实现"
14 | - type: textarea
15 | id: issue_api_describe
16 | attributes:
17 | label: "建议的 API 是什么样的:"
18 | - type: markdown
19 | attributes:
20 | value: "描述一下希望该功能如何调用"
21 | - type: textarea
22 | id: issue_alternative_solution
23 | attributes:
24 | label: "是否已有其他不错的替代方案:"
25 | - type: markdown
26 | attributes:
27 | value: "如果有其他已实现的方案,可以通过链接或截图描述一下"
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .history
3 | node_modules
4 | /dist
5 | package-lock.json
6 | yarn.lock
7 |
8 | # local env files
9 | .env.local
10 | .env.*.local
11 |
12 | # Log files
13 | npm-debug.log*
14 | yarn-debug.log*
15 | yarn-error.log*
16 |
17 | # Editor directories and files
18 | .idea
19 | .vscode
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Xu Liangzhan
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vxe-table-plugin-element
2 |
3 | [](https://gitee.com/x-extends/vxe-table-plugin-element/stargazers)
4 | [](https://www.npmjs.com/package/vxe-table-plugin-element)
5 | [](http://npm-stat.com/charts.html?package=vxe-table-plugin-element)
6 | [](LICENSE)
7 |
8 | 基于 [vxe-table](https://www.npmjs.com/package/vxe-table) 表格的适配插件,用于兼容 [element-plus](https://github.com/element-plus/element-plus) 组件库
9 |
10 | ## Compatibility
11 |
12 | 对应 vxe-table v4 版本
13 | 如果您使用的是 vxe-table 4.7+ 最新版本,建议使用更强大的 [@vxe-ui/plugin-render-element](https://vxeui.com/other4/#/plugin-render-element/grid/edit/el-input) 适配器,代码完全兼容
14 |
15 | ## Installing
16 |
17 | ```shell
18 | npm install vxe-table@next vxe-table-plugin-element@next element-plus
19 | ```
20 |
21 | ```javascript
22 | // ...
23 | import VXETable from 'vxe-table'
24 | import VXETablePluginElement from 'vxe-table-plugin-element'
25 | import 'vxe-table-plugin-element/dist/style.css'
26 | // ...
27 |
28 | VXETable.use(VXETablePluginElement)
29 | ```
30 |
31 | ## API
32 |
33 | ### cell-render 默认的渲染配置项说明
34 |
35 | | 属性 | 描述 | 类型 | 可选值 | 默认值 |
36 | |------|------|-----|-----|-----|
37 | | name | 支持的渲染组件 | String | ElInput, ElAutocomplete, ElInputNumber, ElSwitch, ElRate, ElSlider, ElButton, ElButtons | — |
38 | | attrs | 渲染组件附加属性,参数请查看被渲染的 Component attrs | Object | — | {} |
39 | | props | 渲染组件附加属性,参数请查看被渲染的 Component props | Object | — | {} |
40 | | options | 只对 name=ElSelect 有效,下拉组件选项列表 | Array | — | [] |
41 | | optionProps | 只对 name=ElSelect 有效,下拉组件选项属性参数配置 | Object | — | { value: 'value', label: 'label' } |
42 | | optionGroups | 只对 name=ElSelect 有效,下拉组件分组选项列表 | Array | — | [] |
43 | | optionGroupProps | 只对 name=ElSelect 有效,下拉组件分组选项属性参数配置 | Object | — | { options: 'options', label: 'label' } |
44 | | events | 渲染组件附加事件,参数为 ( {row,rowIndex,column,columnIndex}, ...Component arguments ) | Object | — | — |
45 | | nativeEvents | 渲染组件附加事件,参数为 ( {row,rowIndex,column,columnIndex}, ...Component arguments ) | Object | — | — |
46 |
47 | ### edit-render 可编辑渲染器配置项说明
48 |
49 | | 属性 | 描述 | 类型 | 可选值 | 默认值 |
50 | |------|------|-----|-----|-----|
51 | | name | 支持的渲染组件 | String | ElInput, ElAutocomplete, ElInputNumber, ElSelect, ElCascader, ElTimeSelect, ElTimePicker, ElDatePicker, ElSwitch, ElRate, ElSlider, ElButton, ElButtons | — |
52 | | attrs | 渲染组件附加属性,参数请查看被渲染的 Component attrs | Object | — | {} |
53 | | props | 渲染组件附加属性,参数请查看被渲染的 Component props | Object | — | {} |
54 | | options | 只对 name=ElSelect 有效,下拉组件选项列表 | Array | — | [] |
55 | | optionProps | 只对 name=ElSelect 有效,下拉组件选项属性参数配置 | Object | — | { value: 'value', label: 'label' } |
56 | | optionGroups | 只对 name=ElSelect 有效,下拉组件分组选项列表 | Array | — | [] |
57 | | optionGroupProps | 只对 name=ElSelect 有效,下拉组件分组选项属性参数配置 | Object | — | { options: 'options', label: 'label' } |
58 | | events | 渲染组件附加事件,参数为 ( {row,rowIndex,column,columnIndex}, ...Component arguments ) | Object | — | — |
59 | | nativeEvents | 渲染组件附加事件,参数为 ( {row,rowIndex,column,columnIndex}, ...Component arguments ) | Object | — | — |
60 |
61 | ### filter-render 筛选渲染器配置项说明
62 |
63 | | 属性 | 描述 | 类型 | 可选值 | 默认值 |
64 | |------|------|-----|-----|-----|
65 | | name | 支持的渲染组件 | String | ElInput, ElInputNumber, ElAutocomplete, ElSelect, ElDatePicker, ElSwitch, ElRate, ElSlider | — |
66 | | attrs | 渲染组件附加属性,参数请查看被渲染的 Component attrs | Object | — | {} |
67 | | props | 渲染组件附加属性,参数请查看被渲染的 Component props | Object | — | {} |
68 | | options | 只对 name=ElSelect 有效,下拉组件选项列表 | Array | — | [] |
69 | | optionProps | 只对 name=ElSelect 有效,下拉组件选项属性参数配置 | Object | — | { value: 'value', label: 'label' } |
70 | | optionGroups | 只对 name=ElSelect 有效,下拉组件分组选项列表 | Array | — | [] |
71 | | optionGroupProps | 只对 name=ElSelect 有效,下拉组件分组选项属性参数配置 | Object | — | { options: 'options', label: 'label' } |
72 | | events | 渲染组件附加事件,参数为 ( {}, ...Component arguments ) | Object | — | — |
73 | | nativeEvents | 渲染组件附加事件,参数为 ( {}, ...Component arguments ) | Object | — | — |
74 |
75 | ### item-render 表单-项渲染器配置项说明
76 |
77 | | 属性 | 描述 | 类型 | 可选值 | 默认值 |
78 | |------|------|-----|-----|-----|
79 | | name | 支持的渲染组件 | String | ElInput, ElInputNumber, ElAutocomplete, ElSelect, ElDatePicker, ElSwitch, ElRate, ElSlider, ElRadio, ElCheckbox, ElButton, ElButtons | — |
80 | | attrs | 渲染组件附加属性,参数请查看被渲染的 Component attrs | Object | — | {} |
81 | | props | 渲染组件附加属性,参数请查看被渲染的 Component props | Object | — | {} |
82 | | options | 只对 name=ElSelect 有效,下拉组件选项列表 | Array | — | [] |
83 | | optionProps | 只对 name=ElSelect 有效,下拉组件选项属性参数配置 | Object | — | { value: 'value', label: 'label' } |
84 | | optionGroups | 只对 name=ElSelect 有效,下拉组件分组选项列表 | Array | — | [] |
85 | | optionGroupProps | 只对 name=ElSelect 有效,下拉组件分组选项属性参数配置 | Object | — | { options: 'options', label: 'label' } |
86 | | events | 渲染组件附加事件,参数为 ( {}, ...Component arguments ) | Object | — | — |
87 | | nativeEvents | 渲染组件附加事件,参数为 ( {}, ...Component arguments ) | Object | — | — |
88 |
89 | ## Cell demo
90 |
91 | ```html
92 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 | ```
113 |
114 | ```javascript
115 | export default {
116 | data () {
117 | return {
118 | tableData: [
119 | { id: 100, name: 'test0', age: 28, sex: '1', date: null },
120 | { id: 101, name: 'test1', age: 32, sex: '0', date: null },
121 | { id: 102, name: 'test2', age: 36, sex: '1', date: null }
122 | ]
123 | }
124 | }
125 | }
126 | ```
127 |
128 | ## Filter demo
129 |
130 | ```html
131 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 | ```
143 |
144 | ```javascript
145 | import { defineComponent } from 'vue'
146 |
147 | export default defineComponent({
148 | setup () {
149 | return {
150 | tableData: [
151 | { id: 100, name: 'test0', age: 28, date: null },
152 | { id: 101, name: 'test1', age: 32, date: null },
153 | { id: 102, name: 'test2', age: 36, date: null }
154 | ]
155 | }
156 | }
157 | })
158 | ```
159 |
160 | ## License
161 |
162 | [MIT](LICENSE) © 2019-present, Xu Liangzhan
163 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | const gulp = require('gulp')
2 | const del = require('del')
3 | const uglify = require('gulp-uglify')
4 | const babel = require('gulp-babel')
5 | const rename = require('gulp-rename')
6 | // const replace = require('gulp-replace')
7 | const dartSass = require('sass')
8 | const gulpSass = require('gulp-sass')
9 | const sass = gulpSass(dartSass)
10 | const cleanCSS = require('gulp-clean-css')
11 | const prefixer = require('gulp-autoprefixer')
12 | const sourcemaps = require('gulp-sourcemaps')
13 | const ts = require('gulp-typescript')
14 | const pack = require('./package.json')
15 | const tsconfig = require('./tsconfig.json')
16 |
17 | const exportModuleName = 'VXETablePluginElement'
18 |
19 | gulp.task('build_style', function () {
20 | return gulp.src('style.scss')
21 | .pipe(sass())
22 | .pipe(prefixer({
23 | borwsers: ['last 1 version', '> 1%', 'not ie <= 8'],
24 | cascade: true,
25 | remove: true
26 | }))
27 | .pipe(gulp.dest('dist'))
28 | .pipe(cleanCSS())
29 | .pipe(rename({
30 | extname: '.min.css'
31 | }))
32 | .pipe(gulp.dest('dist'))
33 | })
34 |
35 | gulp.task('build_commonjs', function () {
36 | return gulp.src(['index.ts'])
37 | // .pipe(sourcemaps.init())
38 | .pipe(ts(tsconfig.compilerOptions))
39 | .pipe(babel({
40 | presets: ['@babel/env']
41 | }))
42 | .pipe(rename({
43 | basename: 'index',
44 | extname: '.common.js'
45 | }))
46 | // .pipe(sourcemaps.write())
47 | .pipe(gulp.dest('dist'))
48 | })
49 |
50 | gulp.task('build_umd', function () {
51 | return gulp.src(['index.ts'])
52 | .pipe(ts(tsconfig.compilerOptions))
53 | .pipe(babel({
54 | moduleId: pack.name,
55 | presets: ['@babel/env'],
56 | plugins: [['@babel/transform-modules-umd', {
57 | globals: {
58 | [pack.name]: exportModuleName,
59 | vue: 'Vue',
60 | 'vxe-table': 'VXETable',
61 | 'xe-utils': 'XEUtils',
62 | dayjs: 'dayjs'
63 | },
64 | exactGlobals: true
65 | }]]
66 | }))
67 | .pipe(rename({
68 | basename: 'index',
69 | suffix: '.umd',
70 | extname: '.js'
71 | }))
72 | .pipe(gulp.dest('dist'))
73 | .pipe(uglify())
74 | .pipe(rename({
75 | basename: 'index',
76 | suffix: '.umd.min',
77 | extname: '.js'
78 | }))
79 | .pipe(gulp.dest('dist'))
80 | })
81 |
82 | gulp.task('clear', () => {
83 | return del([
84 | 'dist/depend.*'
85 | ])
86 | })
87 |
88 | gulp.task('build', gulp.series(gulp.parallel('build_commonjs', 'build_umd', 'build_style'), 'clear'))
89 |
--------------------------------------------------------------------------------
/index.ts:
--------------------------------------------------------------------------------
1 | import { h, resolveComponent, ComponentOptions } from 'vue'
2 | import XEUtils from 'xe-utils'
3 | import { VXETableCore, VxeTableDefines, VxeColumnPropTypes, VxeGlobalRendererHandles, VxeGlobalInterceptorHandles } from 'vxe-table'
4 |
5 | import dayjs from 'dayjs'
6 |
7 | let vxetable: VXETableCore
8 |
9 | function isEmptyValue (cellValue: any) {
10 | return cellValue === null || cellValue === undefined || cellValue === ''
11 | }
12 |
13 | function getOnName (type: string) {
14 | return 'on' + type.substring(0, 1).toLocaleUpperCase() + type.substring(1)
15 | }
16 |
17 | function getModelProp (renderOpts: VxeGlobalRendererHandles.RenderOptions) {
18 | return 'modelValue'
19 | }
20 |
21 | function getModelEvent (renderOpts: VxeGlobalRendererHandles.RenderOptions) {
22 | return 'update:modelValue'
23 | }
24 |
25 | function getChangeEvent (renderOpts: VxeGlobalRendererHandles.RenderOptions) {
26 | let type = 'change'
27 | switch (renderOpts.name) {
28 | case 'ElAutocomplete':
29 | type = 'select'
30 | break
31 | case 'ElInput':
32 | case 'ElInputNumber':
33 | type = 'input'
34 | break
35 | }
36 | return type
37 | }
38 |
39 | function toDayStringDate (value: any, format: string) {
40 | return dayjs(value, format).date
41 | }
42 |
43 | function toDayDateString (date: any, format: string) {
44 | return dayjs(date).format(format)
45 | }
46 |
47 | function parseDate (value: any, props: { [key: string]: any }) {
48 | return value && props.valueFormat ? toDayStringDate(value, props.valueFormat) : value
49 | }
50 |
51 | function getFormatDate (value: any, props: { [key: string]: any }, defaultFormat: string) {
52 | return value ? toDayDateString(parseDate(value, props), props.format || defaultFormat) : value
53 | }
54 |
55 | function getFormatDates (values: any[], props: { [key: string]: any }, separator: string, defaultFormat: string) {
56 | return XEUtils.map(values, (date: any) => getFormatDate(date, props, defaultFormat)).join(separator)
57 | }
58 |
59 | function equalDaterange (cellValue: any, data: any, props: { [key: string]: any }, defaultFormat: string) {
60 | cellValue = getFormatDate(cellValue, props, defaultFormat)
61 | return cellValue >= getFormatDate(data[0], props, defaultFormat) && cellValue <= getFormatDate(data[1], props, defaultFormat)
62 | }
63 |
64 | function getCellEditFilterProps (renderOpts: any, params: VxeGlobalRendererHandles.RenderEditParams | VxeGlobalRendererHandles.RenderFilterParams, value: any, defaultProps?: { [prop: string]: any }) {
65 | return XEUtils.assign({}, defaultProps, renderOpts.props, { [getModelProp(renderOpts)]: value })
66 | }
67 |
68 | function getItemProps (renderOpts: VxeGlobalRendererHandles.RenderOptions, params: any, value: any, defaultProps?: { [prop: string]: any }) {
69 | return XEUtils.assign({}, defaultProps, renderOpts.props, { [getModelProp(renderOpts)]: value })
70 | }
71 |
72 | function formatText (cellValue: any) {
73 | return '' + (isEmptyValue(cellValue) ? '' : cellValue)
74 | }
75 |
76 | function getCellLabelVNs (renderOpts: VxeColumnPropTypes.EditRender, params: VxeGlobalRendererHandles.RenderCellParams, cellLabel: any) {
77 | const { placeholder } = renderOpts
78 | return [
79 | h('span', {
80 | class: 'vxe-cell--label'
81 | }, placeholder && isEmptyValue(cellLabel)
82 | ? [
83 | h('span', {
84 | class: 'vxe-cell--placeholder'
85 | }, formatText(vxetable._t(placeholder)))
86 | ]
87 | : formatText(cellLabel))
88 | ]
89 | }
90 |
91 | function getOns (renderOpts: VxeGlobalRendererHandles.RenderOptions, params: VxeGlobalRendererHandles.RenderParams, inputFunc?: Function, changeFunc?: Function) {
92 | const { events } = renderOpts
93 | const modelEvent = getModelEvent(renderOpts)
94 | const changeEvent = getChangeEvent(renderOpts)
95 | const isSameEvent = changeEvent === modelEvent
96 | const ons: { [type: string]: Function } = {}
97 | XEUtils.objectEach(events, (func: Function, key: string) => {
98 | ons[getOnName(key)] = function (...args: any[]) {
99 | func(params, ...args)
100 | }
101 | })
102 | if (inputFunc) {
103 | ons[getOnName(modelEvent)] = function (targetEvnt: any) {
104 | inputFunc(targetEvnt)
105 | if (events && events[modelEvent]) {
106 | events[modelEvent](params, targetEvnt)
107 | }
108 | if (isSameEvent && changeFunc) {
109 | changeFunc(targetEvnt)
110 | }
111 | }
112 | }
113 | if (!isSameEvent && changeFunc) {
114 | ons[getOnName(changeEvent)] = function (...args: any[]) {
115 | changeFunc(...args)
116 | if (events && events[changeEvent]) {
117 | events[changeEvent](params, ...args)
118 | }
119 | }
120 | }
121 | return ons
122 | }
123 |
124 | function getEditOns (renderOpts: VxeGlobalRendererHandles.RenderOptions, params: VxeGlobalRendererHandles.RenderEditParams) {
125 | const { $table, row, column } = params
126 | return getOns(renderOpts, params, (value: any) => {
127 | // 处理 model 值双向绑定
128 | XEUtils.set(row, column.field, value)
129 | }, () => {
130 | // 处理 change 事件相关逻辑
131 | $table.updateStatus(params)
132 | })
133 | }
134 |
135 | function getFilterOns (renderOpts: any, params: VxeGlobalRendererHandles.RenderFilterParams, option: VxeTableDefines.FilterOption, changeFunc: Function) {
136 | return getOns(renderOpts, params, (value: any) => {
137 | // 处理 model 值双向绑定
138 | option.data = value
139 | }, changeFunc)
140 | }
141 |
142 | function getItemOns (renderOpts: VxeGlobalRendererHandles.RenderOptions, params: any) {
143 | const { $form, data, field } = params
144 | return getOns(renderOpts, params, (value: any) => {
145 | // 处理 model 值双向绑定
146 | XEUtils.set(data, field, value)
147 | }, () => {
148 | // 处理 change 事件相关逻辑
149 | $form.updateStatus(params)
150 | })
151 | }
152 |
153 | function matchCascaderData (index: number, list: any[], values: any[], labels: any[]) {
154 | const val = values[index]
155 | if (list && values.length > index) {
156 | XEUtils.each(list, (item) => {
157 | if (item.value === val) {
158 | labels.push(item.label)
159 | matchCascaderData(++index, item.children, values, labels)
160 | }
161 | })
162 | }
163 | }
164 |
165 | function getSelectCellValue (renderOpts: VxeColumnPropTypes.EditRender, params: VxeGlobalRendererHandles.RenderCellParams) {
166 | const { options = [], optionGroups, props = {}, optionProps = {}, optionGroupProps = {} } = renderOpts
167 | const { $table, rowid, row, column } = params
168 | const { filterable, multiple } = props
169 | const labelProp = optionProps.label || 'label'
170 | const valueProp = optionProps.value || 'value'
171 | const groupOptions = optionGroupProps.options || 'options'
172 | const cellValue = XEUtils.get(row, column.field)
173 | const colid = column.id
174 | let cellData: any
175 | if (filterable) {
176 | const { internalData } = $table
177 | const { fullAllDataRowIdData } = internalData
178 | const rest: any = fullAllDataRowIdData[rowid]
179 | if (rest) {
180 | cellData = rest.cellData
181 | if (!cellData) {
182 | cellData = rest.cellData = {}
183 | }
184 | }
185 | if (rest && cellData[colid] && cellData[colid].value === cellValue) {
186 | return cellData[colid].label
187 | }
188 | }
189 | if (!isEmptyValue(cellValue)) {
190 | const selectlabel = XEUtils.map(multiple ? cellValue : [cellValue], optionGroups
191 | ? (value) => {
192 | let selectItem: any
193 | for (let index = 0; index < optionGroups.length; index++) {
194 | selectItem = XEUtils.find(optionGroups[index][groupOptions], (item) => item[valueProp] === value)
195 | if (selectItem) {
196 | break
197 | }
198 | }
199 | return selectItem ? selectItem[labelProp] : value
200 | }
201 | : (value) => {
202 | const selectItem = XEUtils.find(options, (item) => item[valueProp] === value)
203 | return selectItem ? selectItem[labelProp] : value
204 | }).join(', ')
205 | if (cellData && options && options.length) {
206 | cellData[colid] = { value: cellValue, label: selectlabel }
207 | }
208 | return selectlabel
209 | }
210 | return ''
211 | }
212 |
213 | function getCascaderCellValue (renderOpts: VxeGlobalRendererHandles.RenderOptions, params: VxeGlobalRendererHandles.RenderCellParams) {
214 | const { props = {} } = renderOpts
215 | const { row, column } = params
216 | const cellValue = XEUtils.get(row, column.field)
217 | const values: any[] = cellValue || []
218 | const labels: any[] = []
219 | matchCascaderData(0, props.options, values, labels)
220 | return (props.showAllLevels === false ? labels.slice(labels.length - 1, labels.length) : labels).join(` ${props.separator || '/'} `)
221 | }
222 |
223 | function getDatePickerCellValue (renderOpts: VxeGlobalRendererHandles.RenderOptions, params: VxeGlobalRendererHandles.RenderCellParams | VxeGlobalRendererHandles.ExportMethodParams) {
224 | const { props = {} } = renderOpts
225 | const { row, column } = params
226 | const { rangeSeparator = '-' } = props
227 | let cellValue = XEUtils.get(row, column.field)
228 | switch (props.type) {
229 | case 'week':
230 | cellValue = getFormatDate(cellValue, props, 'YYYYwWW')
231 | break
232 | case 'month':
233 | cellValue = getFormatDate(cellValue, props, 'YYYY-MM')
234 | break
235 | case 'year':
236 | cellValue = getFormatDate(cellValue, props, 'YYYY')
237 | break
238 | case 'dates':
239 | cellValue = getFormatDates(cellValue, props, ', ', 'YYYY-MM-DD')
240 | break
241 | case 'daterange':
242 | cellValue = getFormatDates(cellValue, props, ` ${rangeSeparator} `, 'YYYY-MM-DD')
243 | break
244 | case 'datetimerange':
245 | cellValue = getFormatDates(cellValue, props, ` ${rangeSeparator} `, 'YYYY-MM-DD HH:ss:mm')
246 | break
247 | case 'monthrange':
248 | cellValue = getFormatDates(cellValue, props, ` ${rangeSeparator} `, 'YYYY-MM')
249 | break
250 | default:
251 | cellValue = getFormatDate(cellValue, props, 'YYYY-MM-DD')
252 | }
253 | return cellValue
254 | }
255 |
256 | function getTimePickerCellValue (renderOpts: VxeGlobalRendererHandles.RenderOptions, params: VxeGlobalRendererHandles.RenderCellParams | VxeGlobalRendererHandles.RenderEditParams) {
257 | const { props = {} } = renderOpts
258 | const { row, column } = params
259 | const { isRange, format = 'hh:mm:ss', rangeSeparator = '-' } = props
260 | let cellValue = XEUtils.get(row, column.field)
261 | if (cellValue && isRange) {
262 | cellValue = XEUtils.map(cellValue, (date) => toDayDateString(parseDate(date, props), format)).join(` ${rangeSeparator} `)
263 | }
264 | return toDayDateString(parseDate(cellValue, props), format)
265 | }
266 |
267 | function createEditRender (defaultProps?: { [key: string]: any }) {
268 | return function (renderOpts: VxeColumnPropTypes.EditRender & { name: string }, params: VxeGlobalRendererHandles.RenderEditParams) {
269 | const { row, column } = params
270 | const { name, attrs } = renderOpts
271 | const cellValue = XEUtils.get(row, column.field)
272 | return [
273 | h(resolveComponent(name), {
274 | ...attrs,
275 | ...getCellEditFilterProps(renderOpts, params, cellValue, defaultProps),
276 | ...getEditOns(renderOpts, params)
277 | })
278 | ]
279 | }
280 | }
281 |
282 | function defaultButtonEditRender (renderOpts: VxeColumnPropTypes.EditRender, params: VxeGlobalRendererHandles.RenderEditParams) {
283 | const { attrs } = renderOpts
284 | return [
285 | h(resolveComponent('el-button'), {
286 | ...attrs,
287 | ...getCellEditFilterProps(renderOpts, params, null),
288 | ...getOns(renderOpts, params)
289 | }, cellText(renderOpts.content))
290 | ]
291 | }
292 |
293 | function defaultButtonsEditRender (renderOpts: VxeColumnPropTypes.EditRender, params: VxeGlobalRendererHandles.RenderEditParams) {
294 | const { children } = renderOpts
295 | if (children) {
296 | return children.map((childRenderOpts: VxeColumnPropTypes.EditRender) => defaultButtonEditRender(childRenderOpts, params)[0])
297 | }
298 | return []
299 | }
300 |
301 | function createFilterRender (defaultProps?: { [key: string]: any }) {
302 | return function (renderOpts: VxeColumnPropTypes.FilterRender & { name: string }, params: VxeGlobalRendererHandles.RenderFilterParams) {
303 | const { column } = params
304 | const { name, attrs } = renderOpts
305 | return [
306 | h('div', {
307 | class: 'vxe-table--filter-element-wrapper'
308 | }, column.filters.map((option, oIndex) => {
309 | const optionValue = option.data
310 | return h(resolveComponent(name), {
311 | key: oIndex,
312 | ...attrs,
313 | ...getCellEditFilterProps(renderOpts, params, optionValue, defaultProps),
314 | ...getFilterOns(renderOpts, params, option, () => {
315 | // 处理 change 事件相关逻辑
316 | handleConfirmFilter(params, !!option.data, option)
317 | })
318 | })
319 | }))
320 | ]
321 | }
322 | }
323 |
324 | function handleConfirmFilter (params: VxeGlobalRendererHandles.RenderFilterParams, checked: boolean, option: VxeTableDefines.FilterOption) {
325 | const { $panel } = params
326 | $panel.changeOption(null, checked, option)
327 | }
328 |
329 | /**
330 | * 模糊匹配
331 | * @param params
332 | */
333 | function defaultFuzzyFilterMethod (params: VxeGlobalRendererHandles.FilterMethodParams) {
334 | const { option, row, column } = params
335 | const { data } = option
336 | const cellValue = XEUtils.get(row, column.field)
337 | return XEUtils.toValueString(cellValue).indexOf(data) > -1
338 | }
339 |
340 | /**
341 | * 精确匹配
342 | * @param params
343 | */
344 | function defaultExactFilterMethod (params: VxeGlobalRendererHandles.FilterMethodParams) {
345 | const { option, row, column } = params
346 | const { data } = option
347 | const cellValue = XEUtils.get(row, column.field)
348 | /* eslint-disable eqeqeq */
349 | return cellValue === data
350 | }
351 |
352 | function renderOptions (options: any[], optionProps: VxeGlobalRendererHandles.RenderOptionProps) {
353 | const labelProp = optionProps.label || 'label'
354 | const valueProp = optionProps.value || 'value'
355 | return XEUtils.map(options, (item, oIndex) => {
356 | return h(resolveComponent('el-option'), {
357 | key: oIndex,
358 | value: item[valueProp],
359 | label: item[labelProp],
360 | disabled: item.disabled
361 | })
362 | })
363 | }
364 |
365 | function cellText (cellValue: any): string[] {
366 | return [formatText(cellValue)]
367 | }
368 |
369 | function createFormItemRender (defaultProps?: { [key: string]: any }) {
370 | return function (renderOpts: VxeGlobalRendererHandles.RenderItemContentOptions & { name: string }, params: any) {
371 | const { data, field } = params
372 | const { name } = renderOpts
373 | const { attrs } = renderOpts
374 | const itemValue = XEUtils.get(data, field)
375 | return [
376 | h(resolveComponent(name), {
377 | ...attrs,
378 | ...getItemProps(renderOpts, params, itemValue, defaultProps),
379 | ...getItemOns(renderOpts, params)
380 | })
381 | ]
382 | }
383 | }
384 |
385 | function defaultButtonItemRender (renderOpts: VxeGlobalRendererHandles.RenderItemContentOptions, params: any) {
386 | const { attrs } = renderOpts
387 | const props = getItemProps(renderOpts, params, null)
388 | return [
389 | h(resolveComponent('el-button') as ComponentOptions, {
390 | ...attrs,
391 | ...props,
392 | ...getOns(renderOpts, params)
393 | }, {
394 | default: () => cellText(renderOpts.content || props.content)
395 | })
396 | ]
397 | }
398 |
399 | function defaultButtonsItemRender (renderOpts: VxeGlobalRendererHandles.RenderItemContentOptions, params: any) {
400 | const { children } = renderOpts
401 | if (children) {
402 | return children.map((childRenderOpts: VxeGlobalRendererHandles.RenderItemContentOptions) => defaultButtonItemRender(childRenderOpts, params)[0])
403 | }
404 | return []
405 | }
406 |
407 | function createExportMethod (getExportCellValue: Function) {
408 | return function (params: VxeGlobalRendererHandles.ExportMethodParams) {
409 | const { row, column, options } = params
410 | return options && options.original ? XEUtils.get(row, column.field) : getExportCellValue(column.editRender || column.cellRender, params)
411 | }
412 | }
413 |
414 | function createFormItemRadioAndCheckboxRender () {
415 | return function (renderOpts: VxeGlobalRendererHandles.RenderItemContentOptions & { name: string }, params: any) {
416 | const { name, options = [], optionProps = {}, attrs } = renderOpts
417 | const { data, field } = params
418 | const labelProp = optionProps.label || 'label'
419 | const valueProp = optionProps.value || 'value'
420 | const itemValue = XEUtils.get(data, field)
421 | return [
422 | h(resolveComponent(`${name}Group`) as ComponentOptions, {
423 | ...attrs,
424 | ...getItemProps(renderOpts, params, itemValue),
425 | ...getItemOns(renderOpts, params)
426 | }, {
427 | default: () => {
428 | return options.map((option, oIndex) => {
429 | return h(resolveComponent(name) as ComponentOptions, {
430 | key: oIndex,
431 | label: option[valueProp],
432 | disabled: option.disabled
433 | }, {
434 | default: () => cellText(option[labelProp])
435 | })
436 | })
437 | }
438 | })
439 | ]
440 | }
441 | }
442 |
443 | /**
444 | * 检查触发源是否属于目标节点
445 | */
446 | function getEventTargetNode (evnt: any, container: HTMLElement, className: string) {
447 | let targetElem
448 | let target = evnt.target
449 | while (target && target.nodeType && target !== document) {
450 | if (className && target.className && target.className.split && target.className.split(' ').indexOf(className) > -1) {
451 | targetElem = target
452 | } else if (target === container) {
453 | return { flag: className ? !!targetElem : true, container, targetElem: targetElem }
454 | }
455 | target = target.parentNode
456 | }
457 | return { flag: false }
458 | }
459 |
460 | /**
461 | * 事件兼容性处理
462 | */
463 | function handleClearEvent (params: VxeGlobalInterceptorHandles.InterceptorClearFilterParams | VxeGlobalInterceptorHandles.InterceptorClearEditParams | VxeGlobalInterceptorHandles.InterceptorClearAreasParams) {
464 | const { $event } = params
465 | const bodyElem = document.body
466 | if (
467 | // 远程搜索
468 | getEventTargetNode($event, bodyElem, 'el-autocomplete-suggestion').flag ||
469 | // 下拉框
470 | getEventTargetNode($event, bodyElem, 'el-select-dropdown').flag ||
471 | // 级联
472 | getEventTargetNode($event, bodyElem, 'el-cascader__dropdown').flag ||
473 | getEventTargetNode($event, bodyElem, 'el-cascader-menus').flag ||
474 | // 日期
475 | getEventTargetNode($event, bodyElem, 'el-time-panel').flag ||
476 | getEventTargetNode($event, bodyElem, 'el-picker-panel').flag ||
477 | // 颜色
478 | getEventTargetNode($event, bodyElem, 'el-color-dropdown').flag
479 | ) {
480 | return false
481 | }
482 | }
483 |
484 | /**
485 | * 基于 vxe-table 的表格适配插件,用于兼容 element-ui 组件库
486 | */
487 | export const VXETablePluginElement = {
488 | install (vxetable: VXETableCore) {
489 | // 检查版本
490 | if (!/^(4)\./.test(vxetable.version) && !/v4/i.test((vxetable as any).v)) {
491 | console.error('[vxe-table-plugin-element 4.x] Version vxe-table 4.x is required')
492 | }
493 |
494 | vxetable.renderer.mixin({
495 | ElAutocomplete: {
496 | autofocus: 'input.el-input__inner',
497 | renderDefault: createEditRender(),
498 | renderEdit: createEditRender(),
499 | renderFilter: createFilterRender(),
500 | defaultFilterMethod: defaultExactFilterMethod,
501 | renderItemContent: createFormItemRender()
502 | },
503 | ElInput: {
504 | autofocus: 'input.el-input__inner',
505 | renderDefault: createEditRender(),
506 | renderEdit: createEditRender(),
507 | renderFilter: createFilterRender(),
508 | defaultFilterMethod: defaultFuzzyFilterMethod,
509 | renderItemContent: createFormItemRender()
510 | },
511 | ElInputNumber: {
512 | autofocus: 'input.el-input__inner',
513 | renderDefault: createEditRender(),
514 | renderEdit: createEditRender(),
515 | renderFilter: createFilterRender(),
516 | defaultFilterMethod: defaultFuzzyFilterMethod,
517 | renderItemContent: createFormItemRender()
518 | },
519 | ElSelect: {
520 | renderEdit (renderOpts, params) {
521 | const { options = [], optionGroups, optionProps = {}, optionGroupProps = {} } = renderOpts
522 | const { row, column } = params
523 | const { attrs } = renderOpts
524 | const cellValue = XEUtils.get(row, column.field)
525 | const props = getCellEditFilterProps(renderOpts, params, cellValue)
526 | const ons = getEditOns(renderOpts, params)
527 | if (optionGroups) {
528 | const groupOptions = optionGroupProps.options || 'options'
529 | const groupLabel = optionGroupProps.label || 'label'
530 | return [
531 | h(resolveComponent('el-select') as ComponentOptions, {
532 | ...attrs,
533 | ...props,
534 | ...ons
535 | }, {
536 | default: () => {
537 | return XEUtils.map(optionGroups, (group, gIndex) => {
538 | return h(resolveComponent('el-option-group') as ComponentOptions, {
539 | key: gIndex,
540 | label: group[groupLabel]
541 | }, {
542 | default: () => renderOptions(group[groupOptions], optionProps)
543 | })
544 | })
545 | }
546 | })
547 | ]
548 | }
549 | return [
550 | h(resolveComponent('el-select') as ComponentOptions, {
551 | ...props,
552 | ...attrs,
553 | ...ons
554 | }, {
555 | default: () => renderOptions(options, optionProps)
556 | })
557 | ]
558 | },
559 | renderCell (renderOpts, params) {
560 | return getCellLabelVNs(renderOpts, params, getSelectCellValue(renderOpts, params))
561 | },
562 | renderFilter (renderOpts, params) {
563 | const { options = [], optionGroups, optionProps = {}, optionGroupProps = {} } = renderOpts
564 | const groupOptions = optionGroupProps.options || 'options'
565 | const groupLabel = optionGroupProps.label || 'label'
566 | const { column } = params
567 | const { attrs } = renderOpts
568 | return [
569 | h('div', {
570 | class: 'vxe-table--filter-element-wrapper'
571 | }, optionGroups
572 | ? column.filters.map((option, oIndex) => {
573 | const optionValue = option.data
574 | const props = getCellEditFilterProps(renderOpts, params, optionValue)
575 | return h(resolveComponent('el-select') as ComponentOptions, {
576 | key: oIndex,
577 | ...attrs,
578 | ...props,
579 | ...getFilterOns(renderOpts, params, option, () => {
580 | // 处理 change 事件相关逻辑
581 | handleConfirmFilter(params, props.multiple ? (option.data && option.data.length > 0) : !XEUtils.eqNull(option.data), option)
582 | })
583 | }, {
584 | default: () => {
585 | return XEUtils.map(optionGroups, (group, gIndex) => {
586 | return h(resolveComponent('el-option-group') as ComponentOptions, {
587 | key: gIndex,
588 | label: group[groupLabel]
589 | }, {
590 | default: () => renderOptions(group[groupOptions], optionProps)
591 | })
592 | })
593 | }
594 | })
595 | })
596 | : column.filters.map((option, oIndex) => {
597 | const optionValue = option.data
598 | const props = getCellEditFilterProps(renderOpts, params, optionValue)
599 | return h(resolveComponent('el-select') as ComponentOptions, {
600 | key: oIndex,
601 | ...attrs,
602 | ...props,
603 | ...getFilterOns(renderOpts, params, option, () => {
604 | // 处理 change 事件相关逻辑
605 | handleConfirmFilter(params, props.multiple ? (option.data && option.data.length > 0) : !XEUtils.eqNull(option.data), option)
606 | })
607 | }, {
608 | default: () => renderOptions(options, optionProps)
609 | })
610 | }))
611 | ]
612 | },
613 | defaultFilterMethod (params) {
614 | const { option, row, column } = params
615 | const { data } = option
616 | const { field, filterRender: renderOpts } = column
617 | const { props = {} } = renderOpts
618 | const cellValue = XEUtils.get(row, field)
619 | if (props.multiple) {
620 | if (XEUtils.isArray(cellValue)) {
621 | return XEUtils.includeArrays(cellValue, data)
622 | }
623 | return data.indexOf(cellValue) > -1
624 | }
625 | /* eslint-disable eqeqeq */
626 | return cellValue == data
627 | },
628 | renderItemContent (renderOpts, params) {
629 | const { options = [], optionGroups, optionProps = {}, optionGroupProps = {} } = renderOpts
630 | const { data, field } = params
631 | const { attrs } = renderOpts
632 | const itemValue = XEUtils.get(data, field)
633 | const props = getItemProps(renderOpts, params, itemValue)
634 | const ons = getItemOns(renderOpts, params)
635 | if (optionGroups) {
636 | const groupOptions = optionGroupProps.options || 'options'
637 | const groupLabel = optionGroupProps.label || 'label'
638 | return [
639 | h(resolveComponent('el-select') as ComponentOptions, {
640 | ...attrs,
641 | ...props,
642 | ...ons
643 | }, {
644 | default: () => {
645 | return XEUtils.map(optionGroups, (group, gIndex) => {
646 | return h(resolveComponent('el-option-group') as ComponentOptions, {
647 | label: group[groupLabel],
648 | key: gIndex
649 | }, {
650 | default: () => renderOptions(group[groupOptions], optionProps)
651 | })
652 | })
653 | }
654 | })
655 | ]
656 | }
657 | return [
658 | h(resolveComponent('el-select') as ComponentOptions, {
659 | ...attrs,
660 | ...props,
661 | ...ons
662 | }, {
663 | default: () => renderOptions(options, optionProps)
664 | })
665 | ]
666 | },
667 | exportMethod: createExportMethod(getSelectCellValue)
668 | },
669 | ElCascader: {
670 | renderEdit: createEditRender(),
671 | renderCell (renderOpts, params) {
672 | return getCellLabelVNs(renderOpts, params, getCascaderCellValue(renderOpts, params))
673 | },
674 | renderItemContent: createFormItemRender(),
675 | exportMethod: createExportMethod(getCascaderCellValue)
676 | },
677 | ElDatePicker: {
678 | renderEdit: createEditRender(),
679 | renderCell (renderOpts, params) {
680 | return getCellLabelVNs(renderOpts, params, getDatePickerCellValue(renderOpts, params))
681 | },
682 | renderFilter (renderOpts, params) {
683 | const { column } = params
684 | const { name, attrs } = renderOpts
685 | return [
686 | h('div', {
687 | class: 'vxe-table--filter-element-wrapper'
688 | }, column.filters.map((option, oIndex) => {
689 | const optionValue = option.data
690 | return h(resolveComponent(name as string), {
691 | key: oIndex,
692 | ...attrs,
693 | ...getCellEditFilterProps(renderOpts, params, optionValue),
694 | ...getFilterOns(renderOpts, params, option, () => {
695 | // 处理 change 事件相关逻辑
696 | handleConfirmFilter(params, !!option.data, option)
697 | })
698 | })
699 | }))
700 | ]
701 | },
702 | defaultFilterMethod (params) {
703 | const { option, row, column } = params
704 | const { data } = option
705 | const { filterRender: renderOpts } = column
706 | const { props = {} } = renderOpts
707 | const cellValue = XEUtils.get(row, column.field)
708 | if (data) {
709 | switch (props.type) {
710 | case 'daterange':
711 | return equalDaterange(cellValue, data, props, 'YYYY-MM-DD')
712 | case 'datetimerange':
713 | return equalDaterange(cellValue, data, props, 'YYYY-MM-DD HH:ss:mm')
714 | case 'monthrange':
715 | return equalDaterange(cellValue, data, props, 'YYYY-MM')
716 | default:
717 | return cellValue === data
718 | }
719 | }
720 | return false
721 | },
722 | renderItemContent: createFormItemRender(),
723 | exportMethod: createExportMethod(getDatePickerCellValue)
724 | },
725 | ElTimePicker: {
726 | renderEdit: createEditRender(),
727 | renderCell (renderOpts, params) {
728 | return getCellLabelVNs(renderOpts, params, getTimePickerCellValue(renderOpts, params))
729 | },
730 | renderItemContent: createFormItemRender(),
731 | exportMethod: createExportMethod(getTimePickerCellValue)
732 | },
733 | ElTimeSelect: {
734 | renderEdit: createEditRender(),
735 | renderItemContent: createFormItemRender()
736 | },
737 | ElRate: {
738 | renderDefault: createEditRender(),
739 | renderEdit: createEditRender(),
740 | renderFilter: createFilterRender(),
741 | defaultFilterMethod: defaultExactFilterMethod,
742 | renderItemContent: createFormItemRender()
743 | },
744 | ElSwitch: {
745 | renderDefault: createEditRender(),
746 | renderEdit: createEditRender(),
747 | renderFilter (renderOpts, params) {
748 | const { column } = params
749 | const { name, attrs } = renderOpts
750 | return [
751 | h('div', {
752 | class: 'vxe-table--filter-element-wrapper'
753 | }, column.filters.map((option, oIndex) => {
754 | const optionValue = option.data
755 | return h(resolveComponent(name as string), {
756 | key: oIndex,
757 | ...attrs,
758 | ...getCellEditFilterProps(renderOpts, params, optionValue),
759 | ...getFilterOns(renderOpts, params, option, () => {
760 | // 处理 change 事件相关逻辑
761 | handleConfirmFilter(params, XEUtils.isBoolean(option.data), option)
762 | })
763 | })
764 | }))
765 | ]
766 | },
767 | defaultFilterMethod: defaultExactFilterMethod,
768 | renderItemContent: createFormItemRender()
769 | },
770 | ElSlider: {
771 | renderDefault: createEditRender(),
772 | renderEdit: createEditRender(),
773 | renderFilter: createFilterRender(),
774 | defaultFilterMethod: defaultExactFilterMethod,
775 | renderItemContent: createFormItemRender()
776 | },
777 | ElRadio: {
778 | renderItemContent: createFormItemRadioAndCheckboxRender()
779 | },
780 | ElCheckbox: {
781 | renderItemContent: createFormItemRadioAndCheckboxRender()
782 | },
783 | ElButton: {
784 | renderDefault: defaultButtonEditRender,
785 | renderItemContent: defaultButtonItemRender
786 | },
787 | ElButtons: {
788 | renderDefault: defaultButtonsEditRender,
789 | renderItemContent: defaultButtonsItemRender
790 | }
791 | })
792 |
793 | vxetable.interceptor.add('event.clearFilter', handleClearEvent)
794 | vxetable.interceptor.add('event.clearEdit', handleClearEvent)
795 | vxetable.interceptor.add('event.clearAreas', handleClearEvent)
796 | // 兼容老版本
797 | vxetable.interceptor.add('event.clearActived', handleClearEvent)
798 | }
799 | }
800 |
801 | if (typeof window !== 'undefined' && window.VXETable && window.VXETable.use) {
802 | window.VXETable.use(VXETablePluginElement)
803 | }
804 |
805 | export default VXETablePluginElement
806 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vxe-table-plugin-element",
3 | "version": "4.0.4",
4 | "description": "基于 vxe-table 的表格适配插件,用于兼容 element-ui 组件库",
5 | "scripts": {
6 | "lib": "gulp build"
7 | },
8 | "files": [
9 | "types",
10 | "dist",
11 | "*.ts",
12 | "*.d.ts",
13 | "style.scss"
14 | ],
15 | "main": "dist/index.common.js",
16 | "unpkg": "dist/index.umd.js",
17 | "jsdelivr": "dist/index.umd.js",
18 | "style": "dist/style.css",
19 | "typings": "types/index.d.ts",
20 | "devDependencies": {
21 | "@babel/core": "^7.12.3",
22 | "@babel/plugin-transform-runtime": "^7.12.1",
23 | "@babel/preset-env": "^7.12.1",
24 | "@babel/runtime": "^7.12.5",
25 | "@typescript-eslint/eslint-plugin": "^4.6.1",
26 | "@typescript-eslint/parser": "^4.6.1",
27 | "dayjs": "^1.11.5",
28 | "del": "^6.0.0",
29 | "eslint": "^7.13.0",
30 | "eslint-config-prettier": "^6.15.0",
31 | "eslint-config-standard": "^16.0.1",
32 | "eslint-friendly-formatter": "^4.0.1",
33 | "eslint-plugin-import": "^2.22.1",
34 | "eslint-plugin-node": "^11.1.0",
35 | "eslint-plugin-prettier": "^3.1.4",
36 | "eslint-plugin-promise": "^4.2.1",
37 | "eslint-plugin-standard": "^4.0.2",
38 | "eslint-plugin-typescript": "^0.14.0",
39 | "gulp": "^4.0.2",
40 | "gulp-autoprefixer": "^8.0.0",
41 | "gulp-babel": "^8.0.0",
42 | "gulp-clean-css": "^4.3.0",
43 | "gulp-concat": "^2.6.1",
44 | "gulp-rename": "^2.0.0",
45 | "gulp-replace": "^1.1.3",
46 | "gulp-sass": "^5.1.0",
47 | "gulp-sourcemaps": "^3.0.0",
48 | "gulp-typescript": "^5.0.1",
49 | "gulp-uglify": "^3.0.2",
50 | "markdown-doctest": "^1.1.0",
51 | "prettier": "^2.1.2",
52 | "sass": "^1.55.0",
53 | "typescript": "^4.6.4",
54 | "vue": "^3.4.27",
55 | "vxe-table": "~4.6.25"
56 | },
57 | "peerDependencies": {
58 | "vxe-table": "^4.5.0"
59 | },
60 | "repository": {
61 | "type": "git",
62 | "url": "git+https://github.com/x-extends/vxe-table-plugin-element.git"
63 | },
64 | "keywords": [
65 | "vxe-table",
66 | "vxe-table plugins"
67 | ],
68 | "author": {
69 | "name": "Xu Liangzhan",
70 | "email": "xu_liangzhan@163.com"
71 | },
72 | "license": "MIT",
73 | "bugs": {
74 | "url": "https://github.com/x-extends/vxe-table-plugin-element/issues"
75 | },
76 | "homepage": "https://github.com/x-extends/vxe-table-plugin-element#readme"
77 | }
78 |
--------------------------------------------------------------------------------
/style.scss:
--------------------------------------------------------------------------------
1 | $vxe-table-validate-error-color: #f56c6c;
2 |
3 | %ResetBorder {
4 | border: 0;
5 | }
6 |
7 | %SliderStyle {
8 | .el-slider__runway {
9 | margin: 8px 0;
10 | .el-slider__button-wrapper {
11 | z-index: auto;
12 | }
13 | }
14 | }
15 |
16 | %CompWidth {
17 | & > .el-input,
18 | & > .el-autocomplete,
19 | & > .el-input-number,
20 | & > .el-select,
21 | & > .el-cascader,
22 | & > .el-date-editor,
23 | & > .el-slider {
24 | width: 100%;
25 | }
26 | & > .el-color-picker {
27 | vertical-align: middle;
28 | }
29 | }
30 | .vxe-form {
31 | .vxe-form--item-content {
32 | @extend %CompWidth;
33 | }
34 | }
35 | .vxe-table--filter-element-wrapper {
36 | padding: 0.8em 1em;
37 | & > .el-input,
38 | & > .el-input-number,
39 | & > .el-autocomplete,
40 | & > .el-select,
41 | & > .el-rate,
42 | & > .el-slider {
43 | width: 180px;
44 | }
45 | & > .el-slider {
46 | @extend %SliderStyle;
47 | }
48 | }
49 | .vxe-table {
50 | .vxe-cell,
51 | .vxe-tree-cell {
52 | @extend %CompWidth;
53 | & > .el-slider {
54 | @extend %SliderStyle;
55 | }
56 | }
57 | }
58 | .col--valid-error {
59 | & > .vxe-cell,
60 | & > .vxe-tree-cell {
61 | & > .el-input .el-input__inner,
62 | & > .el-autocomplete .el-input__inner,
63 | & > .el-input-number .el-input__inner,
64 | & > .el-select .el-input__inner,
65 | & > .el-cascader .el-input__inner,
66 | & > .el-date-picker .el-input__inner {
67 | border-color: $vxe-table-validate-error-color;
68 | }
69 | }
70 | }
71 | .vxe-table.cell--highlight {
72 | .vxe-cell,
73 | .vxe-tree-cell {
74 | & > .el-input:not(.el-date-editor),
75 | & > .el-autocomplete,
76 | & > .el-select,
77 | & > .el-cascader {
78 | .el-input__inner {
79 | padding: 0;
80 | @extend %ResetBorder;
81 | }
82 | }
83 | & > .el-input-number {
84 | .el-input-number__decrease,
85 | .el-input-number__increase {
86 | @extend %ResetBorder;
87 | }
88 | .el-input__inner {
89 | @extend %ResetBorder;
90 | }
91 | }
92 | & > .el-date-editor {
93 | .el-input__inner {
94 | @extend %ResetBorder;
95 | }
96 | }
97 | }
98 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [
3 | "index.ts"
4 | ],
5 | "compilerOptions": {
6 | "strict": true,
7 | "moduleResolution": "node",
8 | "noImplicitAny": true,
9 | "allowSyntheticDefaultImports": true,
10 | "target": "esnext",
11 | "lib": [
12 | "esnext",
13 | "dom",
14 | "dom.iterable"
15 | ]
16 | }
17 | }
--------------------------------------------------------------------------------
/types/index.d.ts:
--------------------------------------------------------------------------------
1 | import { VXETableCore } from 'vxe-table'
2 |
3 | /**
4 | * 基于 vxe-table 的表格适配插件,用于兼容 element-plus 组件库
5 | */
6 | export declare const VXETablePluginElement: {
7 | install (vxetable: VXETableCore): void
8 | }
9 |
10 | export default VXETablePluginElement
11 |
--------------------------------------------------------------------------------