style:首页
Showing
8 changed files
with
810 additions
and
5 deletions
src/components/CheckBox/checkbox.vue
0 → 100644
1 | <template> | ||
2 | <label class="el-checkbox" :class="[ | ||
3 | border && checkboxSize ? 'el-checkbox--' + checkboxSize : '', | ||
4 | { 'is-disabled': isDisabled }, | ||
5 | { 'is-bordered': border }, | ||
6 | { 'is-checked': isChecked } | ||
7 | ]" :id="id"> | ||
8 | <span class="el-checkbox__input" :class="{ | ||
9 | 'is-disabled': isDisabled, | ||
10 | 'is-checked': isChecked, | ||
11 | 'is-indeterminate': indeterminate, | ||
12 | 'is-focus': focus | ||
13 | }" :tabindex="indeterminate ? 0 : false" :role="indeterminate ? 'checkbox' : false" | ||
14 | :aria-checked="indeterminate ? 'mixed' : false"> | ||
15 | <span class="el-checkbox__inner"></span> | ||
16 | <input v-if="trueLabel || falseLabel" class="el-checkbox__original" type="checkbox" | ||
17 | :aria-hidden="indeterminate ? 'true' : 'false'" :name="name" :disabled="isDisabled" :true-value="trueLabel" | ||
18 | :false-value="falseLabel" v-model="model" @change="handleChange" @focus="focus = true" @blur="focus = false"> | ||
19 | <input v-else class="el-checkbox__original" type="checkbox" :aria-hidden="indeterminate ? 'true' : 'false'" | ||
20 | :disabled="isDisabled" :value="label" :name="name" v-model="model" @change="handleChange" @focus="focus = true" | ||
21 | @blur="focus = false"> | ||
22 | </span> | ||
23 | <span class="el-checkbox__label"> | ||
24 | <slot></slot> | ||
25 | </span> | ||
26 | </label> | ||
27 | </template> | ||
28 | <script> | ||
29 | import Emitter from 'element-ui/src/mixins/emitter'; | ||
30 | |||
31 | export default { | ||
32 | name: 'ElCheckbox', | ||
33 | |||
34 | mixins: [Emitter], | ||
35 | |||
36 | inject: { | ||
37 | elForm: { | ||
38 | default: '' | ||
39 | }, | ||
40 | elFormItem: { | ||
41 | default: '' | ||
42 | } | ||
43 | }, | ||
44 | |||
45 | componentName: 'ElCheckbox', | ||
46 | |||
47 | data () { | ||
48 | return { | ||
49 | selfModel: false, | ||
50 | focus: false, | ||
51 | isLimitExceeded: false | ||
52 | }; | ||
53 | }, | ||
54 | |||
55 | computed: { | ||
56 | model: { | ||
57 | get () { | ||
58 | return this.isGroup | ||
59 | ? this.store : this.value !== undefined | ||
60 | ? this.value : this.selfModel; | ||
61 | }, | ||
62 | |||
63 | set (val) { | ||
64 | if (this.isGroup) { | ||
65 | this.isLimitExceeded = false; | ||
66 | (this._checkboxGroup.min !== undefined && | ||
67 | val.length < this._checkboxGroup.min && | ||
68 | (this.isLimitExceeded = true)); | ||
69 | |||
70 | (this._checkboxGroup.max !== undefined && | ||
71 | val.length > this._checkboxGroup.max && | ||
72 | (this.isLimitExceeded = true)); | ||
73 | |||
74 | this.isLimitExceeded === false && | ||
75 | this.dispatch('ElCheckboxGroup', 'input', [val]); | ||
76 | } else { | ||
77 | this.$emit('input', val); | ||
78 | this.selfModel = val; | ||
79 | } | ||
80 | } | ||
81 | }, | ||
82 | |||
83 | isChecked () { | ||
84 | if ({}.toString.call(this.model) === '[object Boolean]') { | ||
85 | return this.model; | ||
86 | } else if (Array.isArray(this.model)) { | ||
87 | return this.model.indexOf(this.label) > -1; | ||
88 | } else if (this.model !== null && this.model !== undefined) { | ||
89 | return this.model === this.trueLabel; | ||
90 | } | ||
91 | }, | ||
92 | |||
93 | isGroup () { | ||
94 | let parent = this.$parent; | ||
95 | while (parent) { | ||
96 | if (parent.$options.componentName !== 'ElCheckboxGroup') { | ||
97 | parent = parent.$parent; | ||
98 | } else { | ||
99 | this._checkboxGroup = parent; | ||
100 | return true; | ||
101 | } | ||
102 | } | ||
103 | return false; | ||
104 | }, | ||
105 | |||
106 | store () { | ||
107 | return this._checkboxGroup ? this._checkboxGroup.value : this.value; | ||
108 | }, | ||
109 | |||
110 | /* used to make the isDisabled judgment under max/min props */ | ||
111 | isLimitDisabled () { | ||
112 | const { max, min } = this._checkboxGroup; | ||
113 | return !!(max || min) && | ||
114 | (this.model.length >= max && !this.isChecked) || | ||
115 | (this.model.length <= min && this.isChecked); | ||
116 | }, | ||
117 | |||
118 | isDisabled () { | ||
119 | return this.isGroup | ||
120 | ? this._checkboxGroup.disabled || this.disabled || (this.elForm || {}).disabled || this.isLimitDisabled | ||
121 | : this.disabled || (this.elForm || {}).disabled; | ||
122 | }, | ||
123 | |||
124 | _elFormItemSize () { | ||
125 | return (this.elFormItem || {}).elFormItemSize; | ||
126 | }, | ||
127 | |||
128 | checkboxSize () { | ||
129 | const temCheckboxSize = this.size || this._elFormItemSize || (this.$ELEMENT || {}).size; | ||
130 | return this.isGroup | ||
131 | ? this._checkboxGroup.checkboxGroupSize || temCheckboxSize | ||
132 | : temCheckboxSize; | ||
133 | } | ||
134 | }, | ||
135 | |||
136 | props: { | ||
137 | value: {}, | ||
138 | label: {}, | ||
139 | indeterminate: Boolean, | ||
140 | disabled: Boolean, | ||
141 | checked: Boolean, | ||
142 | name: String, | ||
143 | trueLabel: [String, Number], | ||
144 | falseLabel: [String, Number], | ||
145 | id: String, /* 当indeterminate为真时,为controls提供相关连的checkbox的id,表明元素间的控制关系*/ | ||
146 | controls: String, /* 当indeterminate为真时,为controls提供相关连的checkbox的id,表明元素间的控制关系*/ | ||
147 | border: Boolean, | ||
148 | size: String | ||
149 | }, | ||
150 | |||
151 | methods: { | ||
152 | addToStore () { | ||
153 | if ( | ||
154 | Array.isArray(this.model) && | ||
155 | this.model.indexOf(this.label) === -1 | ||
156 | ) { | ||
157 | this.model.push(this.label); | ||
158 | } else { | ||
159 | this.model = this.trueLabel || true; | ||
160 | } | ||
161 | }, | ||
162 | handleChange (ev) { | ||
163 | if (this.isLimitExceeded) return; | ||
164 | let value; | ||
165 | if (ev.target.checked) { | ||
166 | value = this.trueLabel === undefined ? true : this.trueLabel; | ||
167 | } else { | ||
168 | value = this.falseLabel === undefined ? false : this.falseLabel; | ||
169 | } | ||
170 | this.$emit('change', value, ev); | ||
171 | this.$nextTick(() => { | ||
172 | if (this.isGroup) { | ||
173 | this.dispatch('ElCheckboxGroup', 'change', [this._checkboxGroup.value]); | ||
174 | } | ||
175 | }); | ||
176 | } | ||
177 | }, | ||
178 | |||
179 | created () { | ||
180 | this.checked && this.addToStore(); | ||
181 | }, | ||
182 | mounted () { // 为indeterminate元素 添加aria-controls 属性 | ||
183 | if (this.indeterminate) { | ||
184 | this.$el.setAttribute('aria-controls', this.controls); | ||
185 | } | ||
186 | }, | ||
187 | |||
188 | watch: { | ||
189 | value (value) { | ||
190 | this.dispatch('ElFormItem', 'el.form.change', value); | ||
191 | } | ||
192 | } | ||
193 | }; | ||
194 | </script> |
src/components/Tree/src/model/node.js
0 → 100644
This diff is collapsed.
Click to expand it.
src/components/Tree/src/model/tree-store.js
0 → 100644
1 | import Node from './node'; | ||
2 | import { getNodeKey } from './util'; | ||
3 | |||
4 | export default class TreeStore { | ||
5 | constructor(options) { | ||
6 | this.currentNode = null; | ||
7 | this.currentNodeKey = null; | ||
8 | |||
9 | for (let option in options) { | ||
10 | if (options.hasOwnProperty(option)) { | ||
11 | this[option] = options[option]; | ||
12 | } | ||
13 | } | ||
14 | |||
15 | this.nodesMap = {}; | ||
16 | |||
17 | this.root = new Node({ | ||
18 | data: this.data, | ||
19 | store: this | ||
20 | }); | ||
21 | |||
22 | if (this.lazy && this.load) { | ||
23 | const loadFn = this.load; | ||
24 | loadFn(this.root, (data) => { | ||
25 | this.root.doCreateChildren(data); | ||
26 | this._initDefaultCheckedNodes(); | ||
27 | }); | ||
28 | } else { | ||
29 | this._initDefaultCheckedNodes(); | ||
30 | } | ||
31 | } | ||
32 | |||
33 | filter(value) { | ||
34 | const filterNodeMethod = this.filterNodeMethod; | ||
35 | const lazy = this.lazy; | ||
36 | const traverse = function(node) { | ||
37 | const childNodes = node.root ? node.root.childNodes : node.childNodes; | ||
38 | |||
39 | childNodes.forEach((child) => { | ||
40 | child.visible = filterNodeMethod.call(child, value, child.data, child); | ||
41 | |||
42 | traverse(child); | ||
43 | }); | ||
44 | |||
45 | if (!node.visible && childNodes.length) { | ||
46 | let allHidden = true; | ||
47 | allHidden = !childNodes.some(child => child.visible); | ||
48 | |||
49 | if (node.root) { | ||
50 | node.root.visible = allHidden === false; | ||
51 | } else { | ||
52 | node.visible = allHidden === false; | ||
53 | } | ||
54 | } | ||
55 | if (!value) return; | ||
56 | |||
57 | if (node.visible && !node.isLeaf && !lazy) node.expand(); | ||
58 | }; | ||
59 | |||
60 | traverse(this); | ||
61 | } | ||
62 | |||
63 | setData(newVal) { | ||
64 | const instanceChanged = newVal !== this.root.data; | ||
65 | if (instanceChanged) { | ||
66 | this.root.setData(newVal); | ||
67 | this._initDefaultCheckedNodes(); | ||
68 | } else { | ||
69 | this.root.updateChildren(); | ||
70 | } | ||
71 | } | ||
72 | |||
73 | getNode(data) { | ||
74 | if (data instanceof Node) return data; | ||
75 | const key = typeof data !== 'object' ? data : getNodeKey(this.key, data); | ||
76 | return this.nodesMap[key] || null; | ||
77 | } | ||
78 | |||
79 | insertBefore(data, refData) { | ||
80 | const refNode = this.getNode(refData); | ||
81 | refNode.parent.insertBefore({ data }, refNode); | ||
82 | } | ||
83 | |||
84 | insertAfter(data, refData) { | ||
85 | const refNode = this.getNode(refData); | ||
86 | refNode.parent.insertAfter({ data }, refNode); | ||
87 | } | ||
88 | |||
89 | remove(data) { | ||
90 | const node = this.getNode(data); | ||
91 | |||
92 | if (node && node.parent) { | ||
93 | if (node === this.currentNode) { | ||
94 | this.currentNode = null; | ||
95 | } | ||
96 | node.parent.removeChild(node); | ||
97 | } | ||
98 | } | ||
99 | |||
100 | append(data, parentData) { | ||
101 | const parentNode = parentData ? this.getNode(parentData) : this.root; | ||
102 | |||
103 | if (parentNode) { | ||
104 | parentNode.insertChild({ data }); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | _initDefaultCheckedNodes() { | ||
109 | const defaultCheckedKeys = this.defaultCheckedKeys || []; | ||
110 | const nodesMap = this.nodesMap; | ||
111 | |||
112 | defaultCheckedKeys.forEach((checkedKey) => { | ||
113 | const node = nodesMap[checkedKey]; | ||
114 | |||
115 | if (node) { | ||
116 | node.setChecked(true, !this.checkStrictly); | ||
117 | } | ||
118 | }); | ||
119 | } | ||
120 | |||
121 | _initDefaultCheckedNode(node) { | ||
122 | const defaultCheckedKeys = this.defaultCheckedKeys || []; | ||
123 | |||
124 | if (defaultCheckedKeys.indexOf(node.key) !== -1) { | ||
125 | node.setChecked(true, !this.checkStrictly); | ||
126 | } | ||
127 | } | ||
128 | |||
129 | setDefaultCheckedKey(newVal) { | ||
130 | if (newVal !== this.defaultCheckedKeys) { | ||
131 | this.defaultCheckedKeys = newVal; | ||
132 | this._initDefaultCheckedNodes(); | ||
133 | } | ||
134 | } | ||
135 | |||
136 | registerNode(node) { | ||
137 | const key = this.key; | ||
138 | if (!key || !node || !node.data) return; | ||
139 | |||
140 | const nodeKey = node.key; | ||
141 | if (nodeKey !== undefined) this.nodesMap[node.key] = node; | ||
142 | } | ||
143 | |||
144 | deregisterNode(node) { | ||
145 | const key = this.key; | ||
146 | if (!key || !node || !node.data) return; | ||
147 | |||
148 | node.childNodes.forEach(child => { | ||
149 | this.deregisterNode(child); | ||
150 | }); | ||
151 | |||
152 | delete this.nodesMap[node.key]; | ||
153 | } | ||
154 | |||
155 | getCheckedNodes(leafOnly = false, includeHalfChecked = false) { | ||
156 | const checkedNodes = []; | ||
157 | const traverse = function(node) { | ||
158 | const childNodes = node.root ? node.root.childNodes : node.childNodes; | ||
159 | |||
160 | childNodes.forEach((child) => { | ||
161 | if ((child.checked || (includeHalfChecked && child.indeterminate)) && (!leafOnly || (leafOnly && child.isLeaf))) { | ||
162 | checkedNodes.push(child.data); | ||
163 | } | ||
164 | |||
165 | traverse(child); | ||
166 | }); | ||
167 | }; | ||
168 | |||
169 | traverse(this); | ||
170 | |||
171 | return checkedNodes; | ||
172 | } | ||
173 | |||
174 | getCheckedKeys(leafOnly = false) { | ||
175 | return this.getCheckedNodes(leafOnly).map((data) => (data || {})[this.key]); | ||
176 | } | ||
177 | |||
178 | getHalfCheckedNodes() { | ||
179 | const nodes = []; | ||
180 | const traverse = function(node) { | ||
181 | const childNodes = node.root ? node.root.childNodes : node.childNodes; | ||
182 | |||
183 | childNodes.forEach((child) => { | ||
184 | if (child.indeterminate) { | ||
185 | nodes.push(child.data); | ||
186 | } | ||
187 | |||
188 | traverse(child); | ||
189 | }); | ||
190 | }; | ||
191 | |||
192 | traverse(this); | ||
193 | |||
194 | return nodes; | ||
195 | } | ||
196 | |||
197 | getHalfCheckedKeys() { | ||
198 | return this.getHalfCheckedNodes().map((data) => (data || {})[this.key]); | ||
199 | } | ||
200 | |||
201 | _getAllNodes() { | ||
202 | const allNodes = []; | ||
203 | const nodesMap = this.nodesMap; | ||
204 | for (let nodeKey in nodesMap) { | ||
205 | if (nodesMap.hasOwnProperty(nodeKey)) { | ||
206 | allNodes.push(nodesMap[nodeKey]); | ||
207 | } | ||
208 | } | ||
209 | |||
210 | return allNodes; | ||
211 | } | ||
212 | |||
213 | updateChildren(key, data) { | ||
214 | const node = this.nodesMap[key]; | ||
215 | if (!node) return; | ||
216 | const childNodes = node.childNodes; | ||
217 | for (let i = childNodes.length - 1; i >= 0; i--) { | ||
218 | const child = childNodes[i]; | ||
219 | this.remove(child.data); | ||
220 | } | ||
221 | for (let i = 0, j = data.length; i < j; i++) { | ||
222 | const child = data[i]; | ||
223 | this.append(child, node.data); | ||
224 | } | ||
225 | } | ||
226 | |||
227 | _setCheckedKeys(key, leafOnly = false, checkedKeys) { | ||
228 | const allNodes = this._getAllNodes().sort((a, b) => b.level - a.level); | ||
229 | const cache = Object.create(null); | ||
230 | const keys = Object.keys(checkedKeys); | ||
231 | allNodes.forEach(node => node.setChecked(false, false)); | ||
232 | for (let i = 0, j = allNodes.length; i < j; i++) { | ||
233 | const node = allNodes[i]; | ||
234 | const nodeKey = node.data[key].toString(); | ||
235 | let checked = keys.indexOf(nodeKey) > -1; | ||
236 | if (!checked) { | ||
237 | if (node.checked && !cache[nodeKey]) { | ||
238 | node.setChecked(false, false); | ||
239 | } | ||
240 | continue; | ||
241 | } | ||
242 | |||
243 | let parent = node.parent; | ||
244 | while (parent && parent.level > 0) { | ||
245 | cache[parent.data[key]] = true; | ||
246 | parent = parent.parent; | ||
247 | } | ||
248 | |||
249 | if (node.isLeaf || this.checkStrictly) { | ||
250 | node.setChecked(true, false); | ||
251 | continue; | ||
252 | } | ||
253 | node.setChecked(true, true); | ||
254 | |||
255 | if (leafOnly) { | ||
256 | node.setChecked(false, false); | ||
257 | const traverse = function(node) { | ||
258 | const childNodes = node.childNodes; | ||
259 | childNodes.forEach((child) => { | ||
260 | if (!child.isLeaf) { | ||
261 | child.setChecked(false, false); | ||
262 | } | ||
263 | traverse(child); | ||
264 | }); | ||
265 | }; | ||
266 | traverse(node); | ||
267 | } | ||
268 | } | ||
269 | } | ||
270 | |||
271 | setCheckedNodes(array, leafOnly = false) { | ||
272 | const key = this.key; | ||
273 | const checkedKeys = {}; | ||
274 | array.forEach((item) => { | ||
275 | checkedKeys[(item || {})[key]] = true; | ||
276 | }); | ||
277 | |||
278 | this._setCheckedKeys(key, leafOnly, checkedKeys); | ||
279 | } | ||
280 | |||
281 | setCheckedKeys(keys, leafOnly = false) { | ||
282 | this.defaultCheckedKeys = keys; | ||
283 | const key = this.key; | ||
284 | const checkedKeys = {}; | ||
285 | keys.forEach((key) => { | ||
286 | checkedKeys[key] = true; | ||
287 | }); | ||
288 | |||
289 | this._setCheckedKeys(key, leafOnly, checkedKeys); | ||
290 | } | ||
291 | |||
292 | setDefaultExpandedKeys(keys) { | ||
293 | keys = keys || []; | ||
294 | this.defaultExpandedKeys = keys; | ||
295 | |||
296 | keys.forEach((key) => { | ||
297 | const node = this.getNode(key); | ||
298 | if (node) node.expand(null, this.autoExpandParent); | ||
299 | }); | ||
300 | } | ||
301 | |||
302 | setChecked(data, checked, deep) { | ||
303 | const node = this.getNode(data); | ||
304 | |||
305 | if (node) { | ||
306 | node.setChecked(!!checked, deep); | ||
307 | } | ||
308 | } | ||
309 | |||
310 | getCurrentNode() { | ||
311 | return this.currentNode; | ||
312 | } | ||
313 | |||
314 | setCurrentNode(currentNode) { | ||
315 | const prevCurrentNode = this.currentNode; | ||
316 | if (prevCurrentNode) { | ||
317 | prevCurrentNode.isCurrent = false; | ||
318 | } | ||
319 | this.currentNode = currentNode; | ||
320 | this.currentNode.isCurrent = true; | ||
321 | } | ||
322 | |||
323 | setUserCurrentNode(node) { | ||
324 | const key = node[this.key]; | ||
325 | const currNode = this.nodesMap[key]; | ||
326 | this.setCurrentNode(currNode); | ||
327 | } | ||
328 | |||
329 | setCurrentNodeKey(key) { | ||
330 | if (key === null || key === undefined) { | ||
331 | this.currentNode && (this.currentNode.isCurrent = false); | ||
332 | this.currentNode = null; | ||
333 | return; | ||
334 | } | ||
335 | const node = this.getNode(key); | ||
336 | if (node) { | ||
337 | this.setCurrentNode(node); | ||
338 | } | ||
339 | } | ||
340 | }; |
src/components/Tree/src/model/util.js
0 → 100644
1 | export const NODE_KEY = '$treeNodeId'; | ||
2 | |||
3 | export const markNodeData = function(node, data) { | ||
4 | if (!data || data[NODE_KEY]) return; | ||
5 | Object.defineProperty(data, NODE_KEY, { | ||
6 | value: node.id, | ||
7 | enumerable: false, | ||
8 | configurable: false, | ||
9 | writable: false | ||
10 | }); | ||
11 | }; | ||
12 | |||
13 | export const getNodeKey = function(key, data) { | ||
14 | if (!key) return data[NODE_KEY]; | ||
15 | return data[key]; | ||
16 | }; | ||
17 | |||
18 | export const findNearestComponent = (element, componentName) => { | ||
19 | let target = element; | ||
20 | while (target && target.tagName !== 'BODY') { | ||
21 | if (target.__vue__ && target.__vue__.$options.name === componentName) { | ||
22 | return target.__vue__; | ||
23 | } | ||
24 | target = target.parentNode; | ||
25 | } | ||
26 | return null; | ||
27 | }; |
src/components/Tree/src/tree-node.vue
0 → 100644
1 | <template> | ||
2 | <div class="el-tree-node" @click.stop="handleClick" @contextmenu="($event) => this.handleContextMenu($event)" | ||
3 | v-show="node.visible" :class="{ | ||
4 | 'is-expanded': expanded, | ||
5 | 'is-current': node.isCurrent, | ||
6 | 'is-hidden': !node.visible, | ||
7 | 'is-focusable': !node.disabled, | ||
8 | 'is-checked': !node.disabled && node.checked | ||
9 | }" role="treeitem" tabindex="-1" :aria-expanded="expanded" :aria-disabled="node.disabled" | ||
10 | :aria-checked="node.checked" :draggable="tree.draggable" @dragstart.stop="handleDragStart" | ||
11 | @dragover.stop="handleDragOver" @dragend.stop="handleDragEnd" @drop.stop="handleDrop" ref="node"> | ||
12 | <div class="el-tree-node__content" :style="{ 'padding-left': (node.level - 1) * tree.indent + 'px' }"> | ||
13 | <span @click.stop="handleExpandIconClick" :class="[ | ||
14 | { 'is-leaf': node.isLeaf, expanded: !node.isLeaf && expanded }, | ||
15 | 'el-tree-node__expand-icon', | ||
16 | tree.iconClass ? tree.iconClass : 'el-icon-caret-right' | ||
17 | ]"> | ||
18 | </span> | ||
19 | <CheckBox v-if="showCheckbox" v-model="node.checked" :indeterminate="node.indeterminate" | ||
20 | :disabled="!!node.disabled" @click.native.stop @change="handleCheckChange"> | ||
21 | <node-content :node="node"></node-content> | ||
22 | </CheckBox> | ||
23 | |||
24 | </div> | ||
25 | <el-collapse-transition> | ||
26 | <div class="el-tree-node__children" v-if="!renderAfterExpand || childNodeRendered" v-show="expanded" role="group" | ||
27 | :aria-expanded="expanded"> | ||
28 | <el-tree-node :render-content="renderContent" v-for="child in node.childNodes" | ||
29 | :render-after-expand="renderAfterExpand" :show-checkbox="showCheckbox" :key="getNodeKey(child)" :node="child" | ||
30 | @node-expand="handleChildNodeExpand"> | ||
31 | </el-tree-node> | ||
32 | </div> | ||
33 | </el-collapse-transition> | ||
34 | </div> | ||
35 | </template> | ||
36 | |||
37 | <script type="text/jsx"> | ||
38 | import CheckBox from '@/components/CheckBox/checkbox' | ||
39 | import ElCollapseTransition from 'element-ui/src/transitions/collapse-transition'; | ||
40 | import ElCheckbox from 'element-ui/packages/checkbox'; | ||
41 | import emitter from 'element-ui/src/mixins/emitter'; | ||
42 | import { getNodeKey } from './model/util'; | ||
43 | |||
44 | export default { | ||
45 | name: 'ElTreeNode', | ||
46 | |||
47 | componentName: 'ElTreeNode', | ||
48 | |||
49 | mixins: [emitter], | ||
50 | |||
51 | props: { | ||
52 | node: { | ||
53 | default () { | ||
54 | return {}; | ||
55 | } | ||
56 | }, | ||
57 | props: {}, | ||
58 | renderContent: Function, | ||
59 | renderAfterExpand: { | ||
60 | type: Boolean, | ||
61 | default: true | ||
62 | }, | ||
63 | showCheckbox: { | ||
64 | type: Boolean, | ||
65 | default: false | ||
66 | } | ||
67 | }, | ||
68 | |||
69 | components: { | ||
70 | ElCollapseTransition, | ||
71 | ElCheckbox, | ||
72 | CheckBox, | ||
73 | NodeContent: { | ||
74 | props: { | ||
75 | node: { | ||
76 | required: true | ||
77 | } | ||
78 | }, | ||
79 | render (h) { | ||
80 | const parent = this.$parent; | ||
81 | const tree = parent.tree; | ||
82 | const node = this.node; | ||
83 | const { data, store } = node; | ||
84 | return ( | ||
85 | <span class="el-tree-node__label">{node.label}</span> | ||
86 | ); | ||
87 | } | ||
88 | } | ||
89 | }, | ||
90 | |||
91 | data () { | ||
92 | return { | ||
93 | tree: null, | ||
94 | expanded: false, | ||
95 | childNodeRendered: false, | ||
96 | oldChecked: null, | ||
97 | oldIndeterminate: null | ||
98 | }; | ||
99 | }, | ||
100 | |||
101 | watch: { | ||
102 | 'node.indeterminate' (val) { | ||
103 | this.handleSelectChange(this.node.checked, val); | ||
104 | }, | ||
105 | |||
106 | 'node.checked' (val) { | ||
107 | this.handleSelectChange(val, this.node.indeterminate); | ||
108 | }, | ||
109 | |||
110 | 'node.expanded' (val) { | ||
111 | this.$nextTick(() => this.expanded = val); | ||
112 | if (val) { | ||
113 | this.childNodeRendered = true; | ||
114 | } | ||
115 | } | ||
116 | }, | ||
117 | |||
118 | methods: { | ||
119 | getNodeKey (node) { | ||
120 | return getNodeKey(this.tree.nodeKey, node.data); | ||
121 | }, | ||
122 | |||
123 | handleSelectChange (checked, indeterminate) { | ||
124 | if (this.oldChecked !== checked && this.oldIndeterminate !== indeterminate) { | ||
125 | this.tree.$emit('check-change', this.node.data, checked, indeterminate); | ||
126 | } | ||
127 | this.oldChecked = checked; | ||
128 | this.indeterminate = indeterminate; | ||
129 | }, | ||
130 | |||
131 | handleClick () { | ||
132 | const store = this.tree.store; | ||
133 | store.setCurrentNode(this.node); | ||
134 | this.tree.$emit('current-change', store.currentNode ? store.currentNode.data : null, store.currentNode); | ||
135 | this.tree.currentNode = this; | ||
136 | if (this.tree.expandOnClickNode) { | ||
137 | this.handleExpandIconClick(); | ||
138 | } | ||
139 | if (this.tree.checkOnClickNode && !this.node.disabled) { | ||
140 | this.handleCheckChange(null, { | ||
141 | target: { checked: !this.node.checked } | ||
142 | }); | ||
143 | } | ||
144 | this.tree.$emit('node-click', this.node.data, this.node, this); | ||
145 | }, | ||
146 | |||
147 | handleContextMenu (event) { | ||
148 | if (this.tree._events['node-contextmenu'] && this.tree._events['node-contextmenu'].length > 0) { | ||
149 | event.stopPropagation(); | ||
150 | event.preventDefault(); | ||
151 | } | ||
152 | this.tree.$emit('node-contextmenu', event, this.node.data, this.node, this); | ||
153 | }, | ||
154 | |||
155 | handleExpandIconClick () { | ||
156 | if (this.node.isLeaf) return; | ||
157 | if (this.expanded) { | ||
158 | this.tree.$emit('node-collapse', this.node.data, this.node, this); | ||
159 | this.node.collapse(); | ||
160 | } else { | ||
161 | this.node.expand(); | ||
162 | this.$emit('node-expand', this.node.data, this.node, this); | ||
163 | } | ||
164 | }, | ||
165 | |||
166 | handleCheckChange (value, ev) { | ||
167 | this.node.setChecked(ev.target.checked, !this.tree.checkStrictly); | ||
168 | this.$nextTick(() => { | ||
169 | const store = this.tree.store; | ||
170 | this.tree.$emit('check', this.node.data, { | ||
171 | checkedNodes: store.getCheckedNodes(), | ||
172 | checkedKeys: store.getCheckedKeys(), | ||
173 | halfCheckedNodes: store.getHalfCheckedNodes(), | ||
174 | halfCheckedKeys: store.getHalfCheckedKeys(), | ||
175 | }); | ||
176 | }); | ||
177 | }, | ||
178 | |||
179 | handleChildNodeExpand (nodeData, node, instance) { | ||
180 | this.broadcast('ElTreeNode', 'tree-node-expand', node); | ||
181 | this.tree.$emit('node-expand', nodeData, node, instance); | ||
182 | }, | ||
183 | |||
184 | handleDragStart (event) { | ||
185 | if (!this.tree.draggable) return; | ||
186 | this.tree.$emit('tree-node-drag-start', event, this); | ||
187 | }, | ||
188 | |||
189 | handleDragOver (event) { | ||
190 | if (!this.tree.draggable) return; | ||
191 | this.tree.$emit('tree-node-drag-over', event, this); | ||
192 | event.preventDefault(); | ||
193 | }, | ||
194 | |||
195 | handleDrop (event) { | ||
196 | event.preventDefault(); | ||
197 | }, | ||
198 | |||
199 | handleDragEnd (event) { | ||
200 | if (!this.tree.draggable) return; | ||
201 | this.tree.$emit('tree-node-drag-end', event, this); | ||
202 | } | ||
203 | }, | ||
204 | |||
205 | created () { | ||
206 | const parent = this.$parent; | ||
207 | |||
208 | if (parent.isTree) { | ||
209 | this.tree = parent; | ||
210 | } else { | ||
211 | this.tree = parent.tree; | ||
212 | } | ||
213 | |||
214 | const tree = this.tree; | ||
215 | if (!tree) { | ||
216 | console.warn('Can not find node\'s tree.'); | ||
217 | } | ||
218 | |||
219 | const props = tree.props || {}; | ||
220 | const childrenKey = props['children'] || 'children'; | ||
221 | |||
222 | this.$watch(`node.data.${childrenKey}`, () => { | ||
223 | this.node.updateChildren(); | ||
224 | }); | ||
225 | |||
226 | if (this.node.expanded) { | ||
227 | this.expanded = true; | ||
228 | this.childNodeRendered = true; | ||
229 | } | ||
230 | |||
231 | if (this.tree.accordion) { | ||
232 | this.$on('tree-node-expand', node => { | ||
233 | if (this.node !== node) { | ||
234 | this.node.collapse(); | ||
235 | } | ||
236 | }); | ||
237 | } | ||
238 | } | ||
239 | }; | ||
240 | </script> |
src/components/Tree/src/tree.vue
0 → 100644
This diff is collapsed.
Click to expand it.
1 | <template> | 1 | <template> |
2 | <dialogBox title="配置常办项目" @submitForm="submitForm" saveButton="保存" :isFullscreen="false" width="50%" | 2 | <dialogBox title="配置常办项目" @submitForm="submitForm" saveButton="保存" :isFullscreen="false" width="50%" |
3 | @closeDialog="closeDialog" v-model="myValue"> | 3 | @closeDialog="closeDialog" v-model="myValue"> |
4 | <el-tree :data="projectList" show-checkbox node-key="id" :default-checked-keys="defaultCheckeds" ref="tree" | 4 | <Tree :data="projectList" show-checkbox node-key="id" :default-checked-keys="defaultCheckeds" ref="tree" |
5 | default-expand-all :props="defaultProps" @check-change="handleClick"></el-tree> | 5 | default-expand-all :props="defaultProps" @check-change="handleClick" /> |
6 | </dialogBox> | 6 | </dialogBox> |
7 | </template> | 7 | </template> |
8 | <script> | 8 | <script> |
9 | import { getMenuInfo } from "@/api/user.js"; | 9 | import { getMenuInfo } from "@/api/user.js"; |
10 | import Tree from "@/components/Tree/src/tree.vue" | ||
10 | import { saveFrequentProjectsList, getHomeFrequentProjects } from "@/api/user.js"; | 11 | import { saveFrequentProjectsList, getHomeFrequentProjects } from "@/api/user.js"; |
11 | export default { | 12 | export default { |
13 | components: { | ||
14 | Tree | ||
15 | }, | ||
12 | props: { | 16 | props: { |
13 | value: { type: Boolean, default: false }, | 17 | value: { type: Boolean, default: false }, |
14 | bindItem: { type: Array, default: [] } | 18 | bindItem: { type: Array, default: [] } |
... | @@ -73,8 +77,8 @@ export default { | ... | @@ -73,8 +77,8 @@ export default { |
73 | } | 77 | } |
74 | return arr | 78 | return arr |
75 | } | 79 | } |
76 | that.defaultCheckeds = lookForAllId() | 80 | this.defaultCheckeds = lookForAllId() |
77 | console.log(that.defaultCheckeds); | 81 | console.log(this.defaultCheckeds, 'that.defaultCheckedsthat.defaultCheckedsthat.defaultCheckeds'); |
78 | }, | 82 | }, |
79 | dealCheckedItem () { | 83 | dealCheckedItem () { |
80 | }, | 84 | }, | ... | ... |
... | @@ -6,7 +6,7 @@ | ... | @@ -6,7 +6,7 @@ |
6 | <el-card shadow="hover" :body-style="{ padding: '0' }" style="height:260px"> | 6 | <el-card shadow="hover" :body-style="{ padding: '0' }" style="height:260px"> |
7 | <div slot="header" class="flexst"> | 7 | <div slot="header" class="flexst"> |
8 | <h5 class="title">常办项目</h5> | 8 | <h5 class="title">常办项目</h5> |
9 | <el-button type="primary" @click="setFrequencyProject()">配置常办</el-button> | 9 | <el-button type="primary" @click="setFrequencyProject">配置常办</el-button> |
10 | </div> | 10 | </div> |
11 | <ul class="workbench flexst"> | 11 | <ul class="workbench flexst"> |
12 | <li v-for="(item, index) in projectList" @click="handleProject(item)" class="pointer" :key="index" | 12 | <li v-for="(item, index) in projectList" @click="handleProject(item)" class="pointer" :key="index" | ... | ... |
-
Please register or sign in to post a comment