@ddwl/ddwl-ui 1.1.5 → 1.1.7

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.
@@ -1,295 +1,292 @@
1
- <!-- eslint-disable vue/no-template-shadow -->
2
- <!-- 多功能筛选树 -->
3
- <template>
4
- <div class="d-filter-tree">
5
- <slot name="header" />
6
- <el-input
7
- v-if="filterable"
8
- v-model="searchContent"
9
- type="text"
10
- :placeholder="placeholder"
11
- suffix-icon="el-icon-search"
12
- />
13
- <el-tree
14
- ref="tree"
15
- class="filter-tree mt16"
16
- :data="data"
17
- :node-key="nodeKey"
18
- :expand-on-click-node="false"
19
- highlight-current
20
- :props="props"
21
- :filter-node-method="filterNode"
22
- :default-expanded-keys="defaultExpandIds"
23
- v-bind="$attrs"
24
- @node-click="nodeClick"
25
- @node-expand="(data)=>handleNodeToggle(data,true)"
26
- @node-collapse="(data)=>handleNodeToggle(data,false)"
27
- v-on="$listeners"
28
- >
29
- <span
30
- slot-scope="{ node, data }"
31
- class="d-filter-tree-node"
32
- >
33
- <span class="node-label ellipsis">
34
- <slot
35
- name="label"
36
- :data="data"
37
- >{{ node.label }}</slot>
38
- </span>
39
- <span class="mr8">
40
- <el-button
41
- v-if="showNodeButton('append', data)"
42
- type="text"
43
- icon="el-icon-plus"
44
- @click.stop="append(node)"
45
- />
46
- <el-button
47
- v-if="showNodeButton('edit', data)"
48
- type="text"
49
- icon="el-icon-edit"
50
- @click.stop="edit(node)"
51
- />
52
- <el-button
53
- v-if="showNodeButton('remove', data)"
54
- type="text"
55
- icon="el-icon-delete"
56
- @click.stop="remove(node)"
57
- />
58
- </span>
59
- </span>
60
- </el-tree>
61
- </div>
62
- </template>
63
-
64
- <script>
65
- import { getNodeByKey, getFirstVaildNode, flatTree } from '@/utils/treeLib'
66
-
67
- export default {
68
- name: 'DFilterTree',
69
- components: {},
70
- props: {
71
- data: {
72
- default: () => [],
73
- type: Array
74
- },
75
- nodeKey: {
76
- default: 'id',
77
- type: String
78
- },
79
- // 默认选中第一个匹配的节点,如果有指定currentKey,则优先选中该节点
80
- // eg: { key: 'id', vlaue: true }
81
- currentDefault: {
82
- default: null,
83
- type: Function
84
- },
85
- // 选中的节点值
86
- currentKey: {
87
- default: '',
88
- type: [String, Number]
89
- },
90
- props: {
91
- default: () => ({}),
92
- type: Object
93
- },
94
- filterable: {
95
- default: true,
96
- type: Boolean
97
- },
98
- showButtons: {
99
- default: false,
100
- type: Boolean
101
- },
102
- templateUrl: {
103
- default: '',
104
- type: String
105
- },
106
- placeholder: {
107
- default: '请输入查询内容',
108
- type: String
109
- },
110
- buttonProps: {
111
- type: Object,
112
- default: () => ({
113
- append: false,
114
- edit: false,
115
- remove: false
116
- })
117
- },
118
- searchKey: {
119
- type: String,
120
- default: 'search'
121
- }
122
- },
123
- data () {
124
- return {
125
- searchContent: '',
126
- defaultExpandIds: [],
127
- first: true
128
- }
129
- },
130
- computed: {
131
- showNodeButton () {
132
- return (type, data) => {
133
- if (this.buttonProps[type]) {
134
- if (typeof this.buttonProps[type] === 'function') {
135
- return this.buttonProps[type](data)
136
- } else {
137
- return true
138
- }
139
- } else {
140
- return false
141
- }
142
- }
143
- }
144
- },
145
- watch: {
146
- data: {
147
- handler () {
148
- if (this.data && this.data.length) {
149
- let node
150
- if (this.currentKey) {
151
- node = getNodeByKey(this.data, this.currentKey, { key: this.nodeKey })
152
- } else if (this.currentDefault) {
153
- // 获取需要默认选中的节点
154
- const props = {
155
- key: this.nodeKey
156
- }
157
- this.props.label && (props.label = this.props.label)
158
- this.props.children && (props.children = this.props.children)
159
- node = getFirstVaildNode(this.data, this.currentDefault, props)
160
- }
161
- this.$nextTick(() => {
162
- if (node) {
163
- this.$refs.tree.setCurrentKey(node[this.nodeKey])
164
- this.$emit('node-change', node)
165
- this.first && this.handleNodeToggle(node, true)
166
- }
167
- this.first = false // 只在第一次有数据时执行默认展开
168
- })
169
- }
170
- },
171
- immediate: true
172
- },
173
- searchContent (val) {
174
- this.$refs.tree.filter(val)
175
- }
176
- },
177
- created () {},
178
- methods: {
179
- // 树的过滤methods
180
- filterNode (value, data) {
181
- if (!value) return true
182
- return (data[this.searchKey] || data[(this.props && this.props.label) || 'label']).indexOf(value) !== -1
183
- },
184
- // 树节点触发点击
185
- nodeClick (node) {
186
- this.$emit('node-change', node)
187
- },
188
- append (node) {
189
- this.$emit('node-append', node)
190
- },
191
- edit (node) {
192
- this.$emit('node-edit', node)
193
- },
194
- remove (node) {
195
- this.$emit('node-remove', node)
196
- },
197
- // 树节点展开/关闭
198
- handleNodeToggle (data, isExpanded) {
199
- if (isExpanded) {
200
- // 展开节点
201
- if (!this.defaultExpandIds.includes(data[this.nodeKey])) {
202
- this.defaultExpandIds.push(data[this.nodeKey])
203
- }
204
- } else {
205
- // 关闭节点
206
- const index = this.defaultExpandIds.indexOf(data[this.nodeKey])
207
- if (index > -1) {
208
- this.defaultExpandIds.splice(index, 1)
209
- }
210
- }
211
- this.removeExpandChildIds(data)
212
- },
213
- removeExpandChildIds (data) {
214
- const ids = (flatTree(data.children || [], { key: this.nodeKey }) || []).map(node => node[this.nodeKey])
215
- this.defaultExpandIds = this.defaultExpandIds.filter(id => !ids.includes(id))
216
- },
217
- expandNode (id) {
218
- const node = getNodeByKey(this.data, id, { key: this.nodeKey })
219
- if (node) this.handleNodeToggle(node, true)
220
- },
221
- // el-tree methods
222
- updateKeyChildren (...args) {
223
- this.$refs.tree.updateKeyChildren(...args)
224
- },
225
- getCheckedNodes (...args) {
226
- return this.$refs.tree.getCheckedNodes(...args)
227
- },
228
- setCheckedNodes (...args) {
229
- this.$refs.tree.setCheckedNodes(...args)
230
- },
231
- getCheckedKeys (...args) {
232
- return this.$refs.tree.getCheckedKeys(...args)
233
- },
234
- setCheckedKeys (...args) {
235
- this.$refs.tree.setCheckedKeys(...args)
236
- },
237
- setChecked (...args) {
238
- this.$refs.tree.setChecked(...args)
239
- },
240
- getHalfCheckedNodes (...args) {
241
- return this.$refs.tree.getHalfCheckedNodes(...args)
242
- },
243
- getHalfCheckedKeys (...args) {
244
- return this.$refs.tree.getHalfCheckedKeys(...args)
245
- },
246
- getCurrentKey (...args) {
247
- return this.$refs.tree.getCurrentKey(...args)
248
- },
249
- getCurrentNode (...args) {
250
- return this.$refs.tree.getCurrentNode(...args)
251
- },
252
- setCurrentKey (...args) {
253
- this.$refs.tree.setCurrentKey(...args)
254
- },
255
- setCurrentNode (...args) {
256
- this.$refs.tree.setCurrentNode(...args)
257
- },
258
- getNode (...args) {
259
- return this.$refs.tree.getNode(...args)
260
- }
261
- }
262
- }
263
- </script>
264
-
265
- <style lang='scss' scoped>
266
- .d-filter-tree {
267
- display: flex;
268
- flex-direction: column;
269
- height: 100%;
270
- font-size: 14px;
271
- .d-filter-tree-buttons {
272
- display: flex;
273
- justify-content: space-between;
274
- & > div {
275
- cursor: pointer;
276
- color: #3786FD;
277
- }
278
- }
279
- .d-filter-tree-node {
280
- display: flex;
281
- align-items: center;
282
- flex: 1;
283
- overflow: hidden;
284
- width: 100%;
285
- .node-label {
286
- flex: 1;
287
- overflow: hidden;
288
- }
289
- }
290
- .filter-tree {
291
- flex: 1;
292
- overflow: auto;
293
- }
294
- }
295
- </style>
1
+ <!-- eslint-disable vue/no-template-shadow -->
2
+ <!-- 多功能筛选树 -->
3
+ <template>
4
+ <div class="d-filter-tree">
5
+ <slot name="header" />
6
+ <el-input
7
+ v-if="filterable"
8
+ v-model="searchContent"
9
+ type="text"
10
+ :placeholder="placeholder"
11
+ suffix-icon="el-icon-search"
12
+ />
13
+ <el-tree
14
+ ref="tree"
15
+ class="filter-tree mt16"
16
+ :data="data"
17
+ :node-key="nodeKey"
18
+ :expand-on-click-node="false"
19
+ highlight-current
20
+ :props="props"
21
+ :filter-node-method="filterNode"
22
+ :default-expanded-keys="defaultExpandIds"
23
+ v-bind="$attrs"
24
+ @node-click="nodeClick"
25
+ @node-expand="(data)=>handleNodeToggle(data,true)"
26
+ @node-collapse="(data)=>handleNodeToggle(data,false)"
27
+ v-on="$listeners"
28
+ >
29
+ <span
30
+ slot-scope="{ node, data }"
31
+ class="d-filter-tree-node"
32
+ >
33
+ <span class="node-label ellipsis">
34
+ <slot
35
+ name="label"
36
+ :data="data"
37
+ >{{ node.label }}</slot>
38
+ </span>
39
+ <span class="mr8">
40
+ <slot name="button" :node="node"></slot>
41
+ <el-button
42
+ v-if="showNodeButton('append', data)"
43
+ type="text"
44
+ icon="el-icon-plus"
45
+ @click.stop="append(node)"
46
+ />
47
+ <el-button
48
+ v-if="showNodeButton('edit', data)"
49
+ type="text"
50
+ icon="el-icon-edit"
51
+ @click.stop="edit(node)"
52
+ />
53
+ <el-button
54
+ v-if="showNodeButton('remove', data)"
55
+ type="text"
56
+ icon="el-icon-delete"
57
+ @click.stop="remove(node)"
58
+ />
59
+ </span>
60
+ </span>
61
+ </el-tree>
62
+ </div>
63
+ </template>
64
+
65
+ <script>
66
+ import { getNodeByKey, getFirstVaildNode, flatTree } from '@/utils/treeLib'
67
+
68
+ export default {
69
+ name: 'DFilterTree',
70
+ components: {},
71
+ props: {
72
+ data: {
73
+ default: () => [],
74
+ type: Array
75
+ },
76
+ nodeKey: {
77
+ default: 'id',
78
+ type: String
79
+ },
80
+ // 默认选中第一个匹配的节点,如果有指定currentKey,则优先选中该节点
81
+ // eg: { key: 'id', vlaue: true }
82
+ currentDefault: {
83
+ default: null,
84
+ type: Function
85
+ },
86
+ // 选中的节点值
87
+ currentKey: {
88
+ default: '',
89
+ type: [String, Number]
90
+ },
91
+ props: {
92
+ default: () => ({}),
93
+ type: Object
94
+ },
95
+ filterable: {
96
+ default: true,
97
+ type: Boolean
98
+ },
99
+ showButtons: {
100
+ default: false,
101
+ type: Boolean
102
+ },
103
+ placeholder: {
104
+ default: '请输入查询内容',
105
+ type: String
106
+ },
107
+ buttonProps: {
108
+ type: Object,
109
+ default: () => ({
110
+ append: false,
111
+ edit: false,
112
+ remove: false
113
+ })
114
+ },
115
+ searchKey: {
116
+ type: String,
117
+ default: 'search'
118
+ }
119
+ },
120
+ data () {
121
+ return {
122
+ searchContent: '',
123
+ defaultExpandIds: [],
124
+ first: true
125
+ }
126
+ },
127
+ computed: {
128
+ showNodeButton () {
129
+ return (type, data) => {
130
+ if (this.buttonProps[type]) {
131
+ if (typeof this.buttonProps[type] === 'function') {
132
+ return this.buttonProps[type](data)
133
+ } else {
134
+ return true
135
+ }
136
+ } else {
137
+ return false
138
+ }
139
+ }
140
+ }
141
+ },
142
+ watch: {
143
+ data: {
144
+ handler () {
145
+ if (this.data && this.data.length) {
146
+ let node
147
+ if (this.currentKey) {
148
+ node = getNodeByKey(this.data, this.currentKey, { key: this.nodeKey })
149
+ } else if (this.currentDefault) {
150
+ // 获取需要默认选中的节点
151
+ const props = {
152
+ key: this.nodeKey
153
+ }
154
+ this.props.label && (props.label = this.props.label)
155
+ this.props.children && (props.children = this.props.children)
156
+ node = getFirstVaildNode(this.data, this.currentDefault, props)
157
+ }
158
+ this.$nextTick(() => {
159
+ if (node) {
160
+ this.$refs.tree.setCurrentKey(node[this.nodeKey])
161
+ this.$emit('node-change', node)
162
+ this.first && this.handleNodeToggle(node, true)
163
+ }
164
+ this.first = false // 只在第一次有数据时执行默认展开
165
+ })
166
+ }
167
+ },
168
+ immediate: true
169
+ },
170
+ searchContent (val) {
171
+ this.$refs.tree.filter(val)
172
+ }
173
+ },
174
+ created () {},
175
+ methods: {
176
+ // 树的过滤methods
177
+ filterNode (value, data) {
178
+ if (!value) return true
179
+ return (data[this.searchKey] || data[(this.props && this.props.label) || 'label']).indexOf(value) !== -1
180
+ },
181
+ // 树节点触发点击
182
+ nodeClick (node) {
183
+ this.$emit('node-change', node)
184
+ },
185
+ append (node) {
186
+ this.$emit('node-append', node)
187
+ },
188
+ edit (node) {
189
+ this.$emit('node-edit', node)
190
+ },
191
+ remove (node) {
192
+ this.$emit('node-remove', node)
193
+ },
194
+ // 树节点展开/关闭
195
+ handleNodeToggle (data, isExpanded) {
196
+ if (isExpanded) {
197
+ // 展开节点
198
+ if (!this.defaultExpandIds.includes(data[this.nodeKey])) {
199
+ this.defaultExpandIds.push(data[this.nodeKey])
200
+ }
201
+ } else {
202
+ // 关闭节点
203
+ const index = this.defaultExpandIds.indexOf(data[this.nodeKey])
204
+ if (index > -1) {
205
+ this.defaultExpandIds.splice(index, 1)
206
+ }
207
+ }
208
+ this.removeExpandChildIds(data)
209
+ },
210
+ removeExpandChildIds (data) {
211
+ const ids = (flatTree(data.children || [], { key: this.nodeKey }) || []).map(node => node[this.nodeKey])
212
+ this.defaultExpandIds = this.defaultExpandIds.filter(id => !ids.includes(id))
213
+ },
214
+ expandNode (id) {
215
+ const node = getNodeByKey(this.data, id, { key: this.nodeKey })
216
+ if (node) this.handleNodeToggle(node, true)
217
+ },
218
+ // el-tree methods
219
+ updateKeyChildren (...args) {
220
+ this.$refs.tree.updateKeyChildren(...args)
221
+ },
222
+ getCheckedNodes (...args) {
223
+ return this.$refs.tree.getCheckedNodes(...args)
224
+ },
225
+ setCheckedNodes (...args) {
226
+ this.$refs.tree.setCheckedNodes(...args)
227
+ },
228
+ getCheckedKeys (...args) {
229
+ return this.$refs.tree.getCheckedKeys(...args)
230
+ },
231
+ setCheckedKeys (...args) {
232
+ this.$refs.tree.setCheckedKeys(...args)
233
+ },
234
+ setChecked (...args) {
235
+ this.$refs.tree.setChecked(...args)
236
+ },
237
+ getHalfCheckedNodes (...args) {
238
+ return this.$refs.tree.getHalfCheckedNodes(...args)
239
+ },
240
+ getHalfCheckedKeys (...args) {
241
+ return this.$refs.tree.getHalfCheckedKeys(...args)
242
+ },
243
+ getCurrentKey (...args) {
244
+ return this.$refs.tree.getCurrentKey(...args)
245
+ },
246
+ getCurrentNode (...args) {
247
+ return this.$refs.tree.getCurrentNode(...args)
248
+ },
249
+ setCurrentKey (...args) {
250
+ this.$refs.tree.setCurrentKey(...args)
251
+ },
252
+ setCurrentNode (...args) {
253
+ this.$refs.tree.setCurrentNode(...args)
254
+ },
255
+ getNode (...args) {
256
+ return this.$refs.tree.getNode(...args)
257
+ }
258
+ }
259
+ }
260
+ </script>
261
+
262
+ <style lang='scss' scoped>
263
+ .d-filter-tree {
264
+ display: flex;
265
+ flex-direction: column;
266
+ height: 100%;
267
+ font-size: 14px;
268
+ .d-filter-tree-buttons {
269
+ display: flex;
270
+ justify-content: space-between;
271
+ & > div {
272
+ cursor: pointer;
273
+ color: #3786FD;
274
+ }
275
+ }
276
+ .d-filter-tree-node {
277
+ display: flex;
278
+ align-items: center;
279
+ flex: 1;
280
+ overflow: hidden;
281
+ width: 100%;
282
+ .node-label {
283
+ flex: 1;
284
+ overflow: hidden;
285
+ }
286
+ }
287
+ .filter-tree {
288
+ flex: 1;
289
+ overflow: auto;
290
+ }
291
+ }
292
+ </style>