sh-view 2.7.9 → 2.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/packages/components/sh-calendar/index.vue +167 -36
- package/packages/components/sh-date/index.vue +37 -9
- package/packages/components/sh-icon/css/font/icons.scss +34 -34
- package/packages/components/sh-image/index.vue +2 -1
- package/packages/components/sh-table/js/tableMethods.js +12 -20
- package/packages/components/sh-tree/components/table-tree.vue +1 -2
- package/packages/components/sh-tree/index.vue +228 -228
- package/packages/vxeTable/css/index.scss +30 -6
- package/packages/vxeTable/render/filters/vxe-filter-input.vue +26 -25
- package/packages/vxeTable/render/filters/vxe-filter-time.vue +26 -0
- package/packages/vxeTable/render/globalRenders.jsx +26 -7
- package/packages/vxeTable/render/mixin/filter-hooks.js +31 -13
|
@@ -23,7 +23,6 @@ import { defineComponent, computed, getCurrentInstance, ref, watch, onMounted }
|
|
|
23
23
|
// 树组件表格默认配置
|
|
24
24
|
const tableConfigDefault = {
|
|
25
25
|
autoResize: true,
|
|
26
|
-
syncResize: true,
|
|
27
26
|
stripe: false,
|
|
28
27
|
size: 'small', // medium / small / mini
|
|
29
28
|
border: 'inner',
|
|
@@ -198,7 +197,7 @@ export default defineComponent({
|
|
|
198
197
|
let searchData = null
|
|
199
198
|
if (filterText) {
|
|
200
199
|
let noSearchArr = ['$vGlobalOption', '$vImg', '$vCheckbox', '$vRadio', '$vUpload', '$vCode', 'seq', 'checkbox', 'radio']
|
|
201
|
-
const searchProps = [{ rkey: labelField, format: labelFormat }]
|
|
200
|
+
const searchProps = [{ rkey: labelField, rname: '', rprops: {}, format: labelFormat }]
|
|
202
201
|
let tableColumnsAll = tableRef.value.getColumns()
|
|
203
202
|
tableColumnsAll.forEach(col => {
|
|
204
203
|
let renderObj = col.cellRender || col.editRender || col.itemRender
|
|
@@ -1,228 +1,228 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="sh-tree" :class="[isSelect ? 'direct' : 'select']" :style="{ height: wrapHeight }">
|
|
3
|
-
<template v-if="isSelect">
|
|
4
|
-
<vxe-pulldown ref="treeSelectRef" class="sh-tree-select" v-bind="selectConfigIn" @hide-panel="onHidePanel">
|
|
5
|
-
<template #default>
|
|
6
|
-
<div class="sh-tree-select-input">
|
|
7
|
-
<vxe-input ref="treeSelectInputRef" :model-value="selectLabels" v-bind="selectInputConfigIn" readonly @focus="onFocus" @clear="onClear"></vxe-input>
|
|
8
|
-
</div>
|
|
9
|
-
</template>
|
|
10
|
-
<template #dropdown>
|
|
11
|
-
<div v-if="filter" class="sh-tree-filter">
|
|
12
|
-
<vxe-input ref="filterInputRef" v-model="filterTextIn" class="sh-tree-filter-input" v-bind="filterInputConfigIn"></vxe-input>
|
|
13
|
-
</div>
|
|
14
|
-
<div class="sh-tree-select-dropdown">
|
|
15
|
-
<table-tree v-if="pulldownDrop" v-bind="tableTreeProps" @datacall="onDataCall" @select="onChange"></table-tree>
|
|
16
|
-
</div>
|
|
17
|
-
</template>
|
|
18
|
-
</vxe-pulldown>
|
|
19
|
-
</template>
|
|
20
|
-
<template v-else>
|
|
21
|
-
<div v-if="filter" class="sh-tree-filter">
|
|
22
|
-
<vxe-input ref="filterInputRef" v-model="filterTextIn" class="sh-tree-filter-input" v-bind="filterInputConfigIn"></vxe-input>
|
|
23
|
-
</div>
|
|
24
|
-
<div class="sh-tree-content" :class="{ 'has-filter': filter }">
|
|
25
|
-
<table-tree v-bind="tableTreeProps" @datacall="onDataCall" @select="onChange"></table-tree>
|
|
26
|
-
</div>
|
|
27
|
-
</template>
|
|
28
|
-
</div>
|
|
29
|
-
</template>
|
|
30
|
-
|
|
31
|
-
<script>
|
|
32
|
-
import { defineComponent, computed, onBeforeMount, getCurrentInstance, ref, watch } from 'vue'
|
|
33
|
-
import './css/index.scss'
|
|
34
|
-
import mixinProps from './mixin/treeProps'
|
|
35
|
-
import tableTree from './components/table-tree.vue'
|
|
36
|
-
export default defineComponent({
|
|
37
|
-
name: 'ShTree',
|
|
38
|
-
components: {
|
|
39
|
-
tableTree
|
|
40
|
-
},
|
|
41
|
-
props: {
|
|
42
|
-
...mixinProps
|
|
43
|
-
},
|
|
44
|
-
emits: ['update:modelValue', 'change', 'focus', 'blur'],
|
|
45
|
-
setup(props, context) {
|
|
46
|
-
const { proxy } = getCurrentInstance()
|
|
47
|
-
const { $vUtils } = proxy
|
|
48
|
-
const { emit, slots } = context
|
|
49
|
-
|
|
50
|
-
const treeSelectRef = ref()
|
|
51
|
-
const treeSelectInputRef = ref()
|
|
52
|
-
const filterInputRef = ref()
|
|
53
|
-
// 公共属性
|
|
54
|
-
const filterTextIn = ref(props.filterText)
|
|
55
|
-
const selectedKeys = ref([])
|
|
56
|
-
const selectedData = ref([])
|
|
57
|
-
const treeData = ref(props.options)
|
|
58
|
-
// 下拉专属属性
|
|
59
|
-
const pulldownDrop = ref(false) // 由于hidePanel延迟350ms关闭,体验不好,这里使用自定义开关
|
|
60
|
-
|
|
61
|
-
const wrapHeight = computed(() => ([100, '100%', 'auto'].includes(props.height) ? '100%' : 'auto'))
|
|
62
|
-
const checkConfig = computed(() => ({ disabled: props.disabled, size: props.size }))
|
|
63
|
-
const selectLabels = computed(() => {
|
|
64
|
-
let { valueData, multiple, format, field, split, labelField } = props
|
|
65
|
-
if (selectedKeys.value && Array.isArray(selectedKeys.value) && selectedKeys.value.length > 0 && treeData.value && treeData.value.length > 0) {
|
|
66
|
-
let selectRows = getSelectRowsByValue(selectedKeys.value)
|
|
67
|
-
let labelFieldList = selectRows.map(item => $vUtils.get(item, labelField))
|
|
68
|
-
if (format) {
|
|
69
|
-
let prefixKey = field
|
|
70
|
-
let endStrs = ['Id', '_id']
|
|
71
|
-
endStrs.forEach(end => {
|
|
72
|
-
if (field.endsWith(end)) {
|
|
73
|
-
prefixKey = field.replace(end, '')
|
|
74
|
-
}
|
|
75
|
-
})
|
|
76
|
-
let dataformat = format.replace(/@/gi, prefixKey)
|
|
77
|
-
if (multiple) {
|
|
78
|
-
let formatKeys = $vUtils.getFormatKeys(dataformat)
|
|
79
|
-
// 首先构建回显数据源,防止formayKeys值不全导致索引错乱
|
|
80
|
-
let formatSourceList = Array.from(new Array(selectedKeys.value.length), (item, itemIndex) => {
|
|
81
|
-
let result = { [field]: selectedKeys.value[itemIndex] }
|
|
82
|
-
formatKeys.forEach(key => {
|
|
83
|
-
result[key] = $vUtils.get(valueData, `${key}[${itemIndex}]`)
|
|
84
|
-
})
|
|
85
|
-
return result
|
|
86
|
-
})
|
|
87
|
-
labelFieldList = formatSourceList.map(item => $vUtils.format(dataformat, item))
|
|
88
|
-
} else {
|
|
89
|
-
labelFieldList = [$vUtils.format(dataformat, valueData)]
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return labelFieldList.join(split)
|
|
93
|
-
}
|
|
94
|
-
return ''
|
|
95
|
-
})
|
|
96
|
-
const selectConfigIn = computed(() => {
|
|
97
|
-
return Object.assign({ transfer: true, popupClassName: 'sh-tree-select-dropdown' }, props.globalConfig?.selectConfig, checkConfig.value)
|
|
98
|
-
})
|
|
99
|
-
const selectInputConfigIn = computed(() => {
|
|
100
|
-
return Object.assign({ clearable: true, controls: false, transfer: false, suffixIcon: 'vxe-icon-caret-down', placeholder: props.placeholder }, props.globalConfig?.inputConfig)
|
|
101
|
-
})
|
|
102
|
-
const filterInputConfigIn = computed(() => {
|
|
103
|
-
return Object.assign({ prefixIcon: 'vxe-icon-search', placeholder: '搜索', clearable: true, controls: false, transfer: true }, props.globalConfig?.filterInputConfig)
|
|
104
|
-
})
|
|
105
|
-
const tableTreeProps = computed(() => {
|
|
106
|
-
return Object.assign({}, props, { filterText: filterTextIn.value, modelValue: selectedKeys.value })
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
// 根据选中值返回选中节点信息
|
|
110
|
-
const getSelectRowsByValue = keys => {
|
|
111
|
-
const { nodeKey, globalConfig } = props
|
|
112
|
-
let childKey = (globalConfig.treeConfig && globalConfig.treeConfig.childrenField) || proxy.$vTableSetup?.table?.treeConfig?.childrenField || 'children'
|
|
113
|
-
let selectRows = []
|
|
114
|
-
$vUtils.eachTree(
|
|
115
|
-
treeData.value,
|
|
116
|
-
node => {
|
|
117
|
-
if (node[nodeKey] && keys.includes(node[nodeKey])) {
|
|
118
|
-
selectRows.push(node)
|
|
119
|
-
}
|
|
120
|
-
},
|
|
121
|
-
{ children: childKey }
|
|
122
|
-
)
|
|
123
|
-
return selectRows
|
|
124
|
-
}
|
|
125
|
-
// 获取选中数据
|
|
126
|
-
const getSelectionData = () => {
|
|
127
|
-
return selectedData.value
|
|
128
|
-
}
|
|
129
|
-
// 树节点获取焦点事件
|
|
130
|
-
const onFocus = async obj => {
|
|
131
|
-
emitFocus()
|
|
132
|
-
treeSelectInputRef.value.blur()
|
|
133
|
-
await treeSelectRef.value.togglePanel()
|
|
134
|
-
pulldownDrop.value = true
|
|
135
|
-
if (filterInputRef.value) filterInputRef.value.focus()
|
|
136
|
-
}
|
|
137
|
-
// 树节点选择变换事件
|
|
138
|
-
const onChange = async (keys, rows, obj) => {
|
|
139
|
-
if (props.isSelect) {
|
|
140
|
-
if (!props.multiple) {
|
|
141
|
-
pulldownDrop.value = false
|
|
142
|
-
selectedKeys.value = keys
|
|
143
|
-
selectedData.value = rows
|
|
144
|
-
await treeSelectRef.value.hidePanel()
|
|
145
|
-
onHidePanel()
|
|
146
|
-
} else {
|
|
147
|
-
selectedKeys.value = keys
|
|
148
|
-
selectedData.value = rows
|
|
149
|
-
}
|
|
150
|
-
return
|
|
151
|
-
}
|
|
152
|
-
selectedKeys.value = keys
|
|
153
|
-
selectedData.value = rows
|
|
154
|
-
emitChange()
|
|
155
|
-
}
|
|
156
|
-
// 树收起下拉回调方法
|
|
157
|
-
const onHidePanel = () => {
|
|
158
|
-
pulldownDrop.value = false
|
|
159
|
-
filterTextIn.value = ''
|
|
160
|
-
emitChange()
|
|
161
|
-
emitBlur()
|
|
162
|
-
}
|
|
163
|
-
// 下拉数清除事件
|
|
164
|
-
const onClear = () => {
|
|
165
|
-
onHidePanel()
|
|
166
|
-
}
|
|
167
|
-
// 表格数据回调
|
|
168
|
-
const onDataCall = datas => {
|
|
169
|
-
treeData.value = datas
|
|
170
|
-
}
|
|
171
|
-
// 回调focus事件
|
|
172
|
-
const emitFocus = obj => {
|
|
173
|
-
emit('focus', obj)
|
|
174
|
-
}
|
|
175
|
-
// 回调change事件
|
|
176
|
-
const emitChange = () => {
|
|
177
|
-
emitValue()
|
|
178
|
-
emit('change', selectedKeys.value, selectedData.value)
|
|
179
|
-
}
|
|
180
|
-
// 回调blur事件
|
|
181
|
-
const emitBlur = () => {
|
|
182
|
-
emit('blur', selectedKeys.value, selectedData.value)
|
|
183
|
-
}
|
|
184
|
-
// 回调双向绑定
|
|
185
|
-
const emitValue = () => {
|
|
186
|
-
emit('update:modelValue', selectedKeys.value)
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
watch(
|
|
190
|
-
() => props.modelValue,
|
|
191
|
-
value => {
|
|
192
|
-
if (pulldownDrop.value) return
|
|
193
|
-
if ($vUtils.isNone(value)) {
|
|
194
|
-
selectedKeys.value = []
|
|
195
|
-
} else {
|
|
196
|
-
selectedKeys.value = Array.isArray(value) ? value : [value]
|
|
197
|
-
}
|
|
198
|
-
},
|
|
199
|
-
{
|
|
200
|
-
immediate: true,
|
|
201
|
-
deep: true
|
|
202
|
-
}
|
|
203
|
-
)
|
|
204
|
-
|
|
205
|
-
return {
|
|
206
|
-
treeSelectRef,
|
|
207
|
-
treeSelectInputRef,
|
|
208
|
-
filterInputRef,
|
|
209
|
-
wrapHeight,
|
|
210
|
-
selectConfigIn,
|
|
211
|
-
selectInputConfigIn,
|
|
212
|
-
filterTextIn,
|
|
213
|
-
filterInputConfigIn,
|
|
214
|
-
pulldownDrop,
|
|
215
|
-
tableTreeProps,
|
|
216
|
-
selectLabels,
|
|
217
|
-
getSelectionData,
|
|
218
|
-
onFocus,
|
|
219
|
-
onClear,
|
|
220
|
-
onHidePanel,
|
|
221
|
-
onDataCall,
|
|
222
|
-
onChange
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
})
|
|
226
|
-
</script>
|
|
227
|
-
|
|
228
|
-
<style lang="scss" scoped></style>
|
|
1
|
+
<template>
|
|
2
|
+
<div class="sh-tree" :class="[isSelect ? 'direct' : 'select']" :style="{ height: wrapHeight }">
|
|
3
|
+
<template v-if="isSelect">
|
|
4
|
+
<vxe-pulldown ref="treeSelectRef" class="sh-tree-select" v-bind="selectConfigIn" @hide-panel="onHidePanel">
|
|
5
|
+
<template #default>
|
|
6
|
+
<div class="sh-tree-select-input">
|
|
7
|
+
<vxe-input ref="treeSelectInputRef" :model-value="selectLabels" v-bind="selectInputConfigIn" readonly @focus="onFocus" @clear="onClear"></vxe-input>
|
|
8
|
+
</div>
|
|
9
|
+
</template>
|
|
10
|
+
<template #dropdown>
|
|
11
|
+
<div v-if="filter" class="sh-tree-filter">
|
|
12
|
+
<vxe-input ref="filterInputRef" v-model="filterTextIn" class="sh-tree-filter-input" v-bind="filterInputConfigIn"></vxe-input>
|
|
13
|
+
</div>
|
|
14
|
+
<div class="sh-tree-select-dropdown">
|
|
15
|
+
<table-tree v-if="pulldownDrop" v-bind="tableTreeProps" @datacall="onDataCall" @select="onChange"></table-tree>
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
18
|
+
</vxe-pulldown>
|
|
19
|
+
</template>
|
|
20
|
+
<template v-else>
|
|
21
|
+
<div v-if="filter" class="sh-tree-filter">
|
|
22
|
+
<vxe-input ref="filterInputRef" v-model="filterTextIn" class="sh-tree-filter-input" v-bind="filterInputConfigIn"></vxe-input>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="sh-tree-content" :class="{ 'has-filter': filter }">
|
|
25
|
+
<table-tree v-bind="tableTreeProps" @datacall="onDataCall" @select="onChange"></table-tree>
|
|
26
|
+
</div>
|
|
27
|
+
</template>
|
|
28
|
+
</div>
|
|
29
|
+
</template>
|
|
30
|
+
|
|
31
|
+
<script>
|
|
32
|
+
import { defineComponent, computed, onBeforeMount, getCurrentInstance, ref, watch } from 'vue'
|
|
33
|
+
import './css/index.scss'
|
|
34
|
+
import mixinProps from './mixin/treeProps'
|
|
35
|
+
import tableTree from './components/table-tree.vue'
|
|
36
|
+
export default defineComponent({
|
|
37
|
+
name: 'ShTree',
|
|
38
|
+
components: {
|
|
39
|
+
tableTree
|
|
40
|
+
},
|
|
41
|
+
props: {
|
|
42
|
+
...mixinProps
|
|
43
|
+
},
|
|
44
|
+
emits: ['update:modelValue', 'change', 'focus', 'blur'],
|
|
45
|
+
setup(props, context) {
|
|
46
|
+
const { proxy } = getCurrentInstance()
|
|
47
|
+
const { $vUtils } = proxy
|
|
48
|
+
const { emit, slots } = context
|
|
49
|
+
|
|
50
|
+
const treeSelectRef = ref()
|
|
51
|
+
const treeSelectInputRef = ref()
|
|
52
|
+
const filterInputRef = ref()
|
|
53
|
+
// 公共属性
|
|
54
|
+
const filterTextIn = ref(props.filterText)
|
|
55
|
+
const selectedKeys = ref([])
|
|
56
|
+
const selectedData = ref([])
|
|
57
|
+
const treeData = ref(props.options)
|
|
58
|
+
// 下拉专属属性
|
|
59
|
+
const pulldownDrop = ref(false) // 由于hidePanel延迟350ms关闭,体验不好,这里使用自定义开关
|
|
60
|
+
|
|
61
|
+
const wrapHeight = computed(() => ([100, '100%', 'auto'].includes(props.height) ? '100%' : 'auto'))
|
|
62
|
+
const checkConfig = computed(() => ({ disabled: props.disabled, size: props.size }))
|
|
63
|
+
const selectLabels = computed(() => {
|
|
64
|
+
let { valueData, multiple, format, field, split, labelField } = props
|
|
65
|
+
if (selectedKeys.value && Array.isArray(selectedKeys.value) && selectedKeys.value.length > 0 && treeData.value && treeData.value.length > 0) {
|
|
66
|
+
let selectRows = getSelectRowsByValue(selectedKeys.value)
|
|
67
|
+
let labelFieldList = selectRows.map(item => $vUtils.get(item, labelField))
|
|
68
|
+
if (format) {
|
|
69
|
+
let prefixKey = field
|
|
70
|
+
let endStrs = ['Id', '_id']
|
|
71
|
+
endStrs.forEach(end => {
|
|
72
|
+
if (field.endsWith(end)) {
|
|
73
|
+
prefixKey = field.replace(end, '')
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
let dataformat = format.replace(/@/gi, prefixKey)
|
|
77
|
+
if (multiple) {
|
|
78
|
+
let formatKeys = $vUtils.getFormatKeys(dataformat)
|
|
79
|
+
// 首先构建回显数据源,防止formayKeys值不全导致索引错乱
|
|
80
|
+
let formatSourceList = Array.from(new Array(selectedKeys.value.length), (item, itemIndex) => {
|
|
81
|
+
let result = { [field]: selectedKeys.value[itemIndex] }
|
|
82
|
+
formatKeys.forEach(key => {
|
|
83
|
+
result[key] = $vUtils.get(valueData, `${key}[${itemIndex}]`)
|
|
84
|
+
})
|
|
85
|
+
return result
|
|
86
|
+
})
|
|
87
|
+
labelFieldList = formatSourceList.map(item => $vUtils.format(dataformat, item))
|
|
88
|
+
} else {
|
|
89
|
+
labelFieldList = [$vUtils.format(dataformat, valueData)]
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return labelFieldList.join(split)
|
|
93
|
+
}
|
|
94
|
+
return ''
|
|
95
|
+
})
|
|
96
|
+
const selectConfigIn = computed(() => {
|
|
97
|
+
return Object.assign({ transfer: true, popupClassName: 'sh-tree-select-dropdown' }, props.globalConfig?.selectConfig, checkConfig.value)
|
|
98
|
+
})
|
|
99
|
+
const selectInputConfigIn = computed(() => {
|
|
100
|
+
return Object.assign({ clearable: true, controls: false, transfer: false, suffixIcon: 'vxe-icon-caret-down', placeholder: props.placeholder }, props.globalConfig?.inputConfig)
|
|
101
|
+
})
|
|
102
|
+
const filterInputConfigIn = computed(() => {
|
|
103
|
+
return Object.assign({ prefixIcon: 'vxe-icon-search', placeholder: '搜索', clearable: true, controls: false, transfer: true }, props.globalConfig?.filterInputConfig)
|
|
104
|
+
})
|
|
105
|
+
const tableTreeProps = computed(() => {
|
|
106
|
+
return Object.assign({}, props, { filterText: filterTextIn.value, modelValue: selectedKeys.value })
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
// 根据选中值返回选中节点信息
|
|
110
|
+
const getSelectRowsByValue = keys => {
|
|
111
|
+
const { nodeKey, globalConfig } = props
|
|
112
|
+
let childKey = (globalConfig.treeConfig && globalConfig.treeConfig.childrenField) || proxy.$vTableSetup?.table?.treeConfig?.childrenField || 'children'
|
|
113
|
+
let selectRows = []
|
|
114
|
+
$vUtils.eachTree(
|
|
115
|
+
treeData.value,
|
|
116
|
+
node => {
|
|
117
|
+
if (node[nodeKey] && keys.includes(node[nodeKey]) && !selectRows.find(row => row[nodeKey] === node[nodeKey])) {
|
|
118
|
+
selectRows.push(node)
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
{ children: childKey }
|
|
122
|
+
)
|
|
123
|
+
return selectRows
|
|
124
|
+
}
|
|
125
|
+
// 获取选中数据
|
|
126
|
+
const getSelectionData = () => {
|
|
127
|
+
return selectedData.value
|
|
128
|
+
}
|
|
129
|
+
// 树节点获取焦点事件
|
|
130
|
+
const onFocus = async obj => {
|
|
131
|
+
emitFocus()
|
|
132
|
+
treeSelectInputRef.value.blur()
|
|
133
|
+
await treeSelectRef.value.togglePanel()
|
|
134
|
+
pulldownDrop.value = true
|
|
135
|
+
if (filterInputRef.value) filterInputRef.value.focus()
|
|
136
|
+
}
|
|
137
|
+
// 树节点选择变换事件
|
|
138
|
+
const onChange = async (keys, rows, obj) => {
|
|
139
|
+
if (props.isSelect) {
|
|
140
|
+
if (!props.multiple) {
|
|
141
|
+
pulldownDrop.value = false
|
|
142
|
+
selectedKeys.value = keys
|
|
143
|
+
selectedData.value = rows
|
|
144
|
+
await treeSelectRef.value.hidePanel()
|
|
145
|
+
onHidePanel()
|
|
146
|
+
} else {
|
|
147
|
+
selectedKeys.value = keys
|
|
148
|
+
selectedData.value = rows
|
|
149
|
+
}
|
|
150
|
+
return
|
|
151
|
+
}
|
|
152
|
+
selectedKeys.value = keys
|
|
153
|
+
selectedData.value = rows
|
|
154
|
+
emitChange()
|
|
155
|
+
}
|
|
156
|
+
// 树收起下拉回调方法
|
|
157
|
+
const onHidePanel = () => {
|
|
158
|
+
pulldownDrop.value = false
|
|
159
|
+
filterTextIn.value = ''
|
|
160
|
+
emitChange()
|
|
161
|
+
emitBlur()
|
|
162
|
+
}
|
|
163
|
+
// 下拉数清除事件
|
|
164
|
+
const onClear = () => {
|
|
165
|
+
onHidePanel()
|
|
166
|
+
}
|
|
167
|
+
// 表格数据回调
|
|
168
|
+
const onDataCall = datas => {
|
|
169
|
+
treeData.value = datas
|
|
170
|
+
}
|
|
171
|
+
// 回调focus事件
|
|
172
|
+
const emitFocus = obj => {
|
|
173
|
+
emit('focus', obj)
|
|
174
|
+
}
|
|
175
|
+
// 回调change事件
|
|
176
|
+
const emitChange = () => {
|
|
177
|
+
emitValue()
|
|
178
|
+
emit('change', selectedKeys.value, selectedData.value)
|
|
179
|
+
}
|
|
180
|
+
// 回调blur事件
|
|
181
|
+
const emitBlur = () => {
|
|
182
|
+
emit('blur', selectedKeys.value, selectedData.value)
|
|
183
|
+
}
|
|
184
|
+
// 回调双向绑定
|
|
185
|
+
const emitValue = () => {
|
|
186
|
+
emit('update:modelValue', selectedKeys.value)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
watch(
|
|
190
|
+
() => props.modelValue,
|
|
191
|
+
value => {
|
|
192
|
+
if (pulldownDrop.value) return
|
|
193
|
+
if ($vUtils.isNone(value)) {
|
|
194
|
+
selectedKeys.value = []
|
|
195
|
+
} else {
|
|
196
|
+
selectedKeys.value = Array.isArray(value) ? value : [value]
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
immediate: true,
|
|
201
|
+
deep: true
|
|
202
|
+
}
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
return {
|
|
206
|
+
treeSelectRef,
|
|
207
|
+
treeSelectInputRef,
|
|
208
|
+
filterInputRef,
|
|
209
|
+
wrapHeight,
|
|
210
|
+
selectConfigIn,
|
|
211
|
+
selectInputConfigIn,
|
|
212
|
+
filterTextIn,
|
|
213
|
+
filterInputConfigIn,
|
|
214
|
+
pulldownDrop,
|
|
215
|
+
tableTreeProps,
|
|
216
|
+
selectLabels,
|
|
217
|
+
getSelectionData,
|
|
218
|
+
onFocus,
|
|
219
|
+
onClear,
|
|
220
|
+
onHidePanel,
|
|
221
|
+
onDataCall,
|
|
222
|
+
onChange
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
})
|
|
226
|
+
</script>
|
|
227
|
+
|
|
228
|
+
<style lang="scss" scoped></style>
|
|
@@ -192,13 +192,37 @@ button:focus, .vxe-button.type--button:not(.is--disabled):focus{
|
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
// 渲染器
|
|
195
|
-
.vxe-filter
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
195
|
+
.vxe-filter{
|
|
196
|
+
&--wrap{
|
|
197
|
+
padding: 8px;
|
|
198
|
+
box-sizing: border-box;
|
|
199
199
|
}
|
|
200
|
-
|
|
201
|
-
|
|
200
|
+
&--input{
|
|
201
|
+
}
|
|
202
|
+
&--list {
|
|
203
|
+
margin: 0;
|
|
204
|
+
padding: 0;
|
|
205
|
+
list-style: none;
|
|
206
|
+
&-head{
|
|
207
|
+
|
|
208
|
+
}
|
|
209
|
+
&-body{
|
|
210
|
+
overflow: auto;
|
|
211
|
+
height: 120px;
|
|
212
|
+
}
|
|
213
|
+
&-item{
|
|
214
|
+
padding: 2px 0;
|
|
215
|
+
display: block;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
&--top{
|
|
219
|
+
position: relative;
|
|
220
|
+
margin-bottom: 5px;
|
|
221
|
+
}
|
|
222
|
+
&--body{
|
|
223
|
+
}
|
|
224
|
+
&--footer{
|
|
225
|
+
margin-top: 5px;
|
|
202
226
|
padding: 5px 0 2px;
|
|
203
227
|
.vxe-button{
|
|
204
228
|
margin-left: 0;
|
|
@@ -1,25 +1,26 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="vxe-filter--wrap">
|
|
3
|
-
<span class="vxe-filter--inner">
|
|
4
|
-
<vxe-input v-model="
|
|
5
|
-
</span>
|
|
6
|
-
</div>
|
|
7
|
-
</template>
|
|
8
|
-
|
|
9
|
-
<script>
|
|
10
|
-
import { defineComponent, getCurrentInstance } from 'vue'
|
|
11
|
-
import cellProps from '../mixin/cell-props'
|
|
12
|
-
import filterHooks from '../mixin/filter-hooks'
|
|
13
|
-
export default defineComponent({
|
|
14
|
-
name: 'VxeFilterInput',
|
|
15
|
-
props: cellProps,
|
|
16
|
-
setup(props, context) {
|
|
17
|
-
const { proxy } = getCurrentInstance()
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
|
|
1
|
+
<template>
|
|
2
|
+
<div class="vxe-filter--wrap">
|
|
3
|
+
<span class="vxe-filter--inner">
|
|
4
|
+
<vxe-input v-model="renderOption.data" v-bind="rprops" :disabled="false" @input="vxeFilterChange" />
|
|
5
|
+
</span>
|
|
6
|
+
</div>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script>
|
|
10
|
+
import { defineComponent, getCurrentInstance, ref, watch } from 'vue'
|
|
11
|
+
import cellProps from '../mixin/cell-props'
|
|
12
|
+
import filterHooks from '../mixin/filter-hooks'
|
|
13
|
+
export default defineComponent({
|
|
14
|
+
name: 'VxeFilterInput',
|
|
15
|
+
props: cellProps,
|
|
16
|
+
setup(props, context) {
|
|
17
|
+
const { proxy } = getCurrentInstance()
|
|
18
|
+
|
|
19
|
+
const useFilter = filterHooks(props, context, proxy)
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
...useFilter
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
</script>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="vxe-filter--wrap">
|
|
3
|
+
<span class="vxe-filter--inner">
|
|
4
|
+
<sh-date v-model="renderOption.data" v-bind="rprops" :disabled="false" @change="vxeFilterChange" />
|
|
5
|
+
</span>
|
|
6
|
+
</div>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script>
|
|
10
|
+
import { defineComponent, getCurrentInstance, reactive, ref } from 'vue'
|
|
11
|
+
import cellProps from '../mixin/cell-props'
|
|
12
|
+
import filterHooks from '../mixin/filter-hooks'
|
|
13
|
+
export default defineComponent({
|
|
14
|
+
name: 'VxeFilterTime',
|
|
15
|
+
props: cellProps,
|
|
16
|
+
setup(props, context) {
|
|
17
|
+
const { proxy } = getCurrentInstance()
|
|
18
|
+
|
|
19
|
+
const useFilter = filterHooks(props, context, proxy)
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
...useFilter
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
</script>
|
|
@@ -29,6 +29,7 @@ import vxeFooterMoney from './footer/vxe-footer-money.vue'
|
|
|
29
29
|
|
|
30
30
|
// 过滤器组件封装
|
|
31
31
|
import vxeFilterInput from './filters/vxe-filter-input.vue'
|
|
32
|
+
import vxeFilterTime from './filters/vxe-filter-time.vue'
|
|
32
33
|
|
|
33
34
|
// 渲染器通用默认配置
|
|
34
35
|
let defaultPublicProps = {
|
|
@@ -54,6 +55,7 @@ let defaultProps = {
|
|
|
54
55
|
$vHref: { disabled: true, target: '_blank' },
|
|
55
56
|
$vUpload: { split: ',' },
|
|
56
57
|
$vFilterInput: { placeholder: '请输入关键词' },
|
|
58
|
+
$vFilterTime: { range: true },
|
|
57
59
|
$vTable: { size: 'mini' },
|
|
58
60
|
$vCode: { placeholder: '请输入', border: true, height: '100px' },
|
|
59
61
|
$vGlobalOption: { type: 'text' }
|
|
@@ -63,11 +65,6 @@ let defaultProps = {
|
|
|
63
65
|
const getFixedProp = (renderOpts, params) => {
|
|
64
66
|
let { name, props = {} } = renderOpts
|
|
65
67
|
let { column, $table } = params
|
|
66
|
-
let writeColumn = !!column
|
|
67
|
-
if (name === '$vFilterInput') {
|
|
68
|
-
writeColumn = false
|
|
69
|
-
name = props.colRenderName
|
|
70
|
-
}
|
|
71
68
|
let rturnProps = Object.assign({}, defaultPublicProps, defaultProps[name], props)
|
|
72
69
|
let transKeys = ['transfer', 'disabled', 'multiple', 'isLeaf', 'commafy', 'border', 'filterable', 'showWordCount', 'editable']
|
|
73
70
|
transKeys.forEach(key => {
|
|
@@ -75,7 +72,7 @@ const getFixedProp = (renderOpts, params) => {
|
|
|
75
72
|
rturnProps[key] = Boolean(+rturnProps[key])
|
|
76
73
|
}
|
|
77
74
|
})
|
|
78
|
-
if (
|
|
75
|
+
if (column) {
|
|
79
76
|
column.rname = name
|
|
80
77
|
column.rprops = rturnProps
|
|
81
78
|
}
|
|
@@ -468,7 +465,7 @@ const filterRenders = {
|
|
|
468
465
|
$vFilterInput: {
|
|
469
466
|
renderFilter(renderOpts, params) {
|
|
470
467
|
let props = getFixedProp(renderOpts, params)
|
|
471
|
-
return [<vxeFilterInput rparams={params} rname={renderOpts.name} rprops={props.rprops} />]
|
|
468
|
+
return [<vxeFilterInput rparams={params} rname={renderOpts.name} rprops={props.rprops} rkey={props.rkey} />]
|
|
472
469
|
},
|
|
473
470
|
filterResetMethod({ options, column }) {
|
|
474
471
|
options.forEach(option => {
|
|
@@ -481,6 +478,28 @@ const filterRenders = {
|
|
|
481
478
|
let { rtext } = utils.formatRender(cellValue, property, row, rname, rprops, { $vUtils: utils })
|
|
482
479
|
return String(rtext).toLowerCase().indexOf(data.toLowerCase()) > -1
|
|
483
480
|
}
|
|
481
|
+
},
|
|
482
|
+
$vFilterTime: {
|
|
483
|
+
renderFilter(renderOpts, params) {
|
|
484
|
+
let props = getFixedProp(renderOpts, params)
|
|
485
|
+
return [<vxeFilterTime rparams={params} rname={renderOpts.name} rprops={props.rprops} rkey={props.rkey} />]
|
|
486
|
+
},
|
|
487
|
+
filterResetMethod({ options, column }) {
|
|
488
|
+
options.forEach(option => {
|
|
489
|
+
option.data = option.resetValue || []
|
|
490
|
+
})
|
|
491
|
+
},
|
|
492
|
+
filterMethod({ value, option, cellValue, row, column, $table }) {
|
|
493
|
+
const { data } = option
|
|
494
|
+
const { rname, rprops, property } = column
|
|
495
|
+
let { rtext } = utils.formatRender(cellValue, property, row, rname, rprops, { $vUtils: utils })
|
|
496
|
+
if (rprops.range || rprops.range === undefined) {
|
|
497
|
+
let startDiff = utils.getDateDiff(data[0], rtext)
|
|
498
|
+
let endDiff = utils.getDateDiff(rtext, data[1])
|
|
499
|
+
return startDiff.done && endDiff.done
|
|
500
|
+
}
|
|
501
|
+
return data === rtext
|
|
502
|
+
}
|
|
484
503
|
}
|
|
485
504
|
}
|
|
486
505
|
|