@@ -171,25 +171,35 @@ export default {
171171 this .$set (node, disabled, node[disabled] || false )
172172 this .$set (node, ' visible' , true )
173173 this .$set (node, ' level' , parent ? ~~ parent .level + 1 : 1 )
174- this .$set (node, ' checked' , Reflect .has (node, ' checked' ) ? node .checked : (parent && parent .checked ) || this .defaultCheckedKeys .indexOf (key) > - 1 )
175- this .$set (node, ' expand' , Reflect .has (node, ' expand' ) ? node .expand : this .defaultExpandAll || this .defaultExpandedKeys .indexOf (key) > - 1 )
174+ this .$set (node, ' checked' , Reflect .has (node, ' checked' ) ? node .checked : (parent && parent .checked ) || this .defaultCheckedKeys .includes (key))
175+ this .$set (node, ' indeterminate' , false )
176+ this .$set (node, ' expand' , Reflect .has (node, ' expand' ) ? node .expand : this .defaultExpandAll || this .defaultExpandedKeys .includes (key))
176177 this .$set (node, ' $keys' , [])
177178 this .$set (node, ' $sort' , 0 )
178179 },
179180 _initData () { // 初始化数据
180181 const { children } = this .defaultProps
181182 const _deep = (arr , parent ) => {
183+ let checkedNum = 0 , anyOne = false
182184 arr .forEach (item => {
183185 this ._initNode (item, parent)
184- item[children]? .length && _deep (item[children], item)
186+ checkedNum += + item .checked
187+ item[children].length && _deep (item[children], item)
185188 item .expand && parent && (parent .expand = true )
189+ if (item .indeterminate ) anyOne = true
186190 })
191+ if (parent) {
192+ // 子节点是否全选 || 子节点的叶子节点全部选中
193+ parent .checked = checkedNum === arr .length || ! this ._levelOrder (arr, item => ! item .checked )
194+ // 子节点有一个是半选 || 被选中的节点不为零并且被选中的节点不等于子节点长度 || 该节点不是全选并且子节点中任意一个被选中
195+ parent .indeterminate = anyOne || (!! checkedNum && checkedNum != arr .length ) || (! parent .checked && !! this ._preorder (arr, item => item .checked ))
196+ }
187197 }
188198 _deep (this .sourceData )
189199 const data = deepCopy (this .sourceData )
190200 this .deepData = this ._getLdqTree (data)
191201 },
192- _getLdqTree (tree ) { // 获取关键词索引并排序, 输入关键词为空时不要走这个方法
202+ _getLdqTree (tree ) { // 获取关键词索引并排序
193203 const { name , children } = this .defaultProps
194204 tree .forEach (item => {
195205 if (this ._search ) {
@@ -215,12 +225,30 @@ export default {
215225 },
216226 _downwardUpdateChecked (data , checked ) { // 向下处理树节点的checked
217227 const { children , disabled } = this .defaultProps
218- // 如果当前节点是叶子节点, 只需要判断disabled
228+ // 如果当前节点是叶子节点, 只需要判断disabled即可
219229 if (! data[children].length ) return ! data[disabled] && (data .checked = checked)
220- // 然后过滤所有叶子节点, 如果全部都是disabled就return
221- if (! this ._levelOrder (data[children], item => ! item[disabled])) return false
222- // 最后判断当前节点是否为disable
223- ! data[disabled] && (data .checked = checked)
230+ // 提前声明变量来合并多次层序遍历
231+ let allNodeIsDisabled = true ,
232+ oneNodeIsDisabledAndChecked = false ,
233+ oneNodeIsDisabledAndUncheck = false
234+ // 遍历所有叶子节点
235+ this ._levelOrder (data[children], item => {
236+ if (! item[disabled]) allNodeIsDisabled = false
237+ if (item[disabled] && item .checked ) oneNodeIsDisabledAndChecked = true
238+ if (item[disabled] && ! item .checked ) oneNodeIsDisabledAndUncheck = true
239+ })
240+ // 如果所有叶子节点都是disabled就提前打断逻辑
241+ if (allNodeIsDisabled) return false
242+ /**
243+ * 如果有一个叶子节点是disabled并且checked=false, 那么该节点只有半选和全不选两种状态
244+ * 如果有一个叶子节点是disabled并且checked=true, 那么该节点只有半选和全选两种状态
245+ */
246+ data .indeterminate = checked ? oneNodeIsDisabledAndUncheck : oneNodeIsDisabledAndChecked
247+ // 默认情况和oneNodeIsDisabledAndChecked时
248+ data .checked = checked
249+ // 由于两种状态可能叠加存在, 所以oneNodeIsDisabledAndUncheck的判断放在后面
250+ if (oneNodeIsDisabledAndUncheck) data .checked = false
251+ // 可以向下继续遍历
224252 data[children].forEach (item => this ._downwardUpdateChecked (item, checked))
225253 },
226254 getNodeByKey (key ) { // 根据key获取对应深拷贝节点
@@ -230,7 +258,7 @@ export default {
230258 return this ._preorder (this .deepData , item => item[this .nodeKey ] == key)
231259 },
232260 resetChecked () { // 取消所有节点的选中状态
233- return ! this ._preorder (this .deepData , item => item .checked = false )
261+ return ! this ._preorder (this .deepData , item => ( item .checked = false , item . indeterminate = false ) )
234262 },
235263 setCheckedByKeys (keys , checked ) { // 设置指定keys节点的checked
236264 if (! keys .length ) return null
0 commit comments