1,前言


最近这段时间在做一个新的模块,其中有一个三层的树结构,产品经理提出了一个很古怪的需求,整的我只能自己控制树的交互,写完之后,感觉对这个组件的用法有了不一样的了解,故而写下来。

2,需求


  • 如果上级节点勾选了,则底下所有节点也勾选
  • 如果是一个个勾选子级节点,直至勾选满所有子级,则该父级节点不能勾选,只能算选中状态
  • 已勾选的节点不能展开,如果是展开了再勾选的,要自动收缩回去

遇见问题:

问题1:后端数据不友好,无唯一key值(有重复key),导致Tree组件无唯一的key

问题2:后端数据不友好,第一层第二层的字段和第三层的字段不一致(第一层字段是dept_id,子集字段是children,第二层子集字段是porjs,第三层字段又是porj_id

问题3:不能使用check-strictly,也就是Tree组件自带的父子关联,只能手动控制checkbox的选中状态

问题4:提交给后端的数据,如果一级二级节点被勾选,则不用传递其下层结构,如果不是被勾选,则需要传递其下层结构

如图:



不过还好这个树结构只有三层,办法还是有的。(如果是未知层级就难了)

3,解决思路


问题1:无唯一key

这个好办,接口请求到数据之后,深拷贝一份,遍历一下,给id手动添加字符来使它们变成唯一的,最后提交的时候去掉前面添加的字符

  1. // 将所有id根据层级加上壹,贰,叁
  2. handlePushLabel(data) {
  3. try {
  4. data.forEach(item1 => {
  5. item1.dept_id += '壹'
  6. if (item1.children && item1.children.length > 0) {
  7. item1.children.forEach(item2 => {
  8. item2.dept_id += '贰'
  9. item2.parent_id += '壹'
  10. if (item2.children.length > 0) {
  11. item2.children.forEach(item3 => {
  12. item3.dept_id += '叁'
  13. item3.parent_id += '贰'
  14. })
  15. }
  16. })
  17. }
  18. })
  19. return data
  20. } catch (error) {
  21. console.warn(error)
  22. }
  23. }
  24. // 将数据的key恢复为原来的
  25. treeList.forEach(item1 => {
  26. item1.dept_id = item1.dept_id.replace('壹', '')
  27. if (item1.children.length > 0) {
  28. item1.children.forEach(item2 => {
  29. item2.dept_id = item2.dept_id.replace('贰', '')
  30. item2.parent_id = item2.parent_id.replace('壹', '')
  31. if (item2.children.length > 0) {
  32. item2.children.forEach(item3 => {
  33. item3.dept_id = item3.dept_id.replace('叁', '')
  34. item3.parent_id = item3.parent_id.replace('贰', '')
  35. })
  36. }
  37. })
  38. }
  39. })

问题2:第一层第二层的字段和第三层的字段不一致

这个也好办,最好的办法是后端调整成一样的,但是如果碰见博主这样的无法沟通的后端,只能前端自己转换字段了,这里采用的是forEach遍历,然后使用map替换对象键名。

  1. // 将树数据的projs字段和proj_id和proj_name改名
  2. handleChangeKey(data) {
  3. try {
  4. const tree = data
  5. tree.forEach(item => {
  6. if (item.children) {
  7. const arr = item.children
  8. // 将projs字段转为children
  9. item.children = arr.map(item1 => {
  10. if (item1.projs.length > 0) {
  11. const obj = item1.projs
  12. const parent_id = item1.dept_id
  13. // 将proj_id字段转为dept_id 将proj_name字段转为dept_name
  14. // 并添加depth深度和父节点id
  15. item1.projs = obj.map(item2 => {
  16. return {
  17. dept_id: item2.proj_id,
  18. dept_name: item2.proj_name,
  19. depth: 3,
  20. parent_id
  21. }
  22. })
  23. }
  24. return {
  25. dept_id: item1.dept_id,
  26. dept_name: item1.dept_name,
  27. depth: item1.depth,
  28. parent_id: item1.parent_id,
  29. children: item1.projs
  30. }
  31. })
  32. }
  33. })
  34. return this.handlePushLabel(tree)
  35. } catch (error) {
  36. console.warn(error)
  37. }
  38. }

问题3:不能使用check-strictly

这个就比较繁琐了,不能使用Tree自带的勾选父子关联(原因看需求2),只能自己手写一二三级节点的勾选逻辑。这样的话,二级和三级节点需要有个parent_id字段,也就是其父级的id,且有一个depth字段,代表其深度1,2,3

  1. <el-tree
  2. @check-change="handleTreeClick"
  3. :data="treeList"
  4. show-checkbox
  5. :default-expand-all="false"
  6. :check-strictly="true"
  7. @node-expand="handleTreeOpen"
  8. node-key="dept_id"
  9. ref="tree"
  10. highlight-current
  11. :props="defaultProps"
  12. />

Tree组件加上ref属性,设置check-strictlytrue,利用@check-change监听节点勾选,利用@node-expand监听节点展开收起,设置node-key为每个节点的id

思路是:通过@check-change的时间回调,拿到第一个参数data,这个data里包含该节点的数据,通过这个数据可以拿到depth判断他是第几层节点,还可以拿到parent_id找到它的上级节点。根据这个区分一二三级节点,然后通过获取到的id,使用this.$refs.tree.getNode(id)可以获取到节点Node。设置节点Nodecheckedtrue,则该节点会变成勾选状态。设置它的indeterminatetrue,则会变成选中状态,设置expandedtrue,则是展开状态。也可以通过this.$refs.tree.setChecked(id, true)来设置选中。

问题4:提交给后端的数据

这个就是坑了,需要先把之前改变的key变回去,还有子级的键名改回去,然后根据是勾选还是只是单纯的选中来拼接数据。在这里用到了getCheckedNodes来获取目前被选中的节点所组成的数组,也用到了getHalfCheckedNodes获取半选中的节点所组成的数组。

4,完整代码


  1. export default {
  2. // 将树数据的projs字段和proj_id和proj_name改名
  3. handleChangeKey(data) {
  4. try {
  5. const tree = data
  6. tree.forEach(item => {
  7. if (item.children) {
  8. const arr = item.children
  9. // 将projs字段转为children
  10. item.children = arr.map(item1 => {
  11. if (item1.projs.length > 0) {
  12. const obj = item1.projs
  13. const parent_id = item1.dept_id
  14. // 将proj_id字段转为dept_id 将proj_name字段转为dept_name
  15. // 并添加depth深度和父节点id
  16. item1.projs = obj.map(item2 => {
  17. return {
  18. dept_id: item2.proj_id,
  19. dept_name: item2.proj_name,
  20. depth: 3,
  21. parent_id
  22. }
  23. })
  24. }
  25. return {
  26. dept_id: item1.dept_id,
  27. dept_name: item1.dept_name,
  28. depth: item1.depth,
  29. parent_id: item1.parent_id,
  30. children: item1.projs
  31. }
  32. })
  33. }
  34. })
  35. return this.handlePushLabel(tree)
  36. } catch (error) {
  37. console.warn(error)
  38. }
  39. },
  40. // 将所有id根据层级加上壹,贰,叁
  41. handlePushLabel(data) {
  42. try {
  43. data.forEach(item1 => {
  44. item1.dept_id += '壹'
  45. if (item1.children && item1.children.length > 0) {
  46. item1.children.forEach(item2 => {
  47. item2.dept_id += '贰'
  48. item2.parent_id += '壹'
  49. if (item2.children.length > 0) {
  50. item2.children.forEach(item3 => {
  51. item3.dept_id += '叁'
  52. item3.parent_id += '贰'
  53. })
  54. }
  55. })
  56. }
  57. })
  58. return data
  59. } catch (error) {
  60. console.warn(error)
  61. }
  62. },
  63. /**
  64. * 树的选中状态发生变化时
  65. * @param {Object} data 该节点的数据
  66. * @param {Object} on 节点本身是否被选中
  67. * @param {Object} child 节点的子树中是否有被选中的节点
  68. */
  69. handleTreeClick(data, on, child) {
  70. try {
  71. this.form.tree = data
  72. if (data.depth === 1) {
  73. this.handleOneNode(on, data)
  74. } else if (data.depth === 2) {
  75. this.handleTwoNode(on, data)
  76. } else if (data.depth === 3) {
  77. this.handleThreeNode(on, data)
  78. }
  79. } catch (error) {
  80. console.warn(error)
  81. }
  82. },
  83. /**
  84. * 一级节点处理
  85. * @param {Boolean} on 是否被选中
  86. * @param {Object} data 当前节点的数据
  87. */
  88. handleOneNode(on, data) {
  89. try {
  90. const tree = this.$refs.tree
  91. // 如果当前节点未被选中且为半选状态
  92. const node = tree.getNode(data.dept_id)
  93. if (node.indeterminate && !node.checked) return
  94. // 如果当前节点被选中则不能展开
  95. if (node.checked && node.expanded) node.expanded = false
  96. // 勾选所有下级
  97. let arr = []
  98. if (data.children.length > 0) {
  99. data.children.forEach(item => {
  100. // 筛选出所有的下级key
  101. arr.push(item.dept_id)
  102. if (item.children.length > 0) {
  103. item.children.forEach(child => {
  104. // 筛选出所有的下下级key
  105. arr.push(child.dept_id)
  106. })
  107. }
  108. })
  109. }
  110. // 选中or取消
  111. if (on) {
  112. arr.forEach(dept => {
  113. tree.setChecked(dept, true)
  114. })
  115. } else {
  116. arr.forEach(dept => {
  117. tree.setChecked(dept, false)
  118. })
  119. }
  120. } catch (error) {
  121. console.warn(error)
  122. }
  123. },
  124. /**
  125. * 二级节点处理
  126. * @param {Boolean} on 是否被选中
  127. * @param {Object} data 当前节点的数据
  128. */
  129. handleTwoNode(on, data) {
  130. try {
  131. const tree = this.$refs.tree
  132. const node = tree.getNode(data.dept_id)
  133. // 如果当前是半选
  134. if (node.indeterminate && !node.checked) return
  135. // 如果当前节点被选中则不能展开
  136. if (node.checked && node.expanded) node.expanded = false
  137. // 上级节点
  138. const parentNode = tree.getNode(data.parent_id)
  139. // 勾选所有下级
  140. let arr = []
  141. if (data.children.length > 0) {
  142. data.children.forEach(item => {
  143. // 筛选出所有的下级key
  144. arr.push(item.dept_id)
  145. })
  146. }
  147. // 选中or取消
  148. if (on) {
  149. arr.forEach(dept => {
  150. tree.setChecked(dept, true)
  151. })
  152. // 如果上级节点不是被勾选则让上级节点半勾选
  153. if (!parentNode.checked) {
  154. parentNode.indeterminate = true
  155. }
  156. } else {
  157. // 先取消所有下级勾选
  158. arr.forEach(dept => {
  159. tree.setChecked(dept, false)
  160. })
  161. // 如果上级节点被勾选则让上级节点半勾选
  162. if (parentNode.checked) {
  163. parentNode.indeterminate = true
  164. // 如果上级是半选,则循环判断下级是否还存在勾选的,来决定上级是否需要去掉半选
  165. } else if (parentNode.indeterminate) {
  166. const parentData = parentNode.data || []
  167. let bool = true
  168. const children = parentData.children
  169. const childArr = []
  170. // 筛选出所有兄弟节点的key
  171. if (children && children.length > 0) {
  172. children.forEach(childItem => {
  173. childArr.push(childItem.dept_id)
  174. })
  175. }
  176. // 循环判断
  177. if (childArr.length > 0) {
  178. for (let i of childArr) {
  179. let thisNode = tree.getNode(i)
  180. // 如果有一个是勾选或者半选
  181. if (thisNode.checked || thisNode.indeterminate) {
  182. bool = false
  183. }
  184. }
  185. }
  186. if (bool) {
  187. parentNode.indeterminate = false
  188. }
  189. }
  190. }
  191. } catch (error) {
  192. console.warn(error)
  193. }
  194. },
  195. /**
  196. * 三级节点处理
  197. * @param {Boolean} on 是否被选中
  198. * @param {Object} data 当前节点的数据
  199. */
  200. handleThreeNode(on, data) {
  201. try {
  202. // 1,如果勾选了,上级节点没选,则把上级节点和上上级改为半选
  203. // 2,如果取消了,上级节点如果是勾选,则把上级节点和上上级改为半选
  204. const tree = this.$refs.tree
  205. // 上级节点
  206. console.log(data)
  207. const parentNode = tree.getNode(data.parent_id)
  208. const forefathersKey = parentNode.data.parent_id
  209. // 祖先节点
  210. console.log(parentNode)
  211. console.log(forefathersKey)
  212. const forefathersNode = tree.getNode(forefathersKey)
  213. console.log(forefathersNode)
  214. // 如果当前节点被勾选
  215. if (on) {
  216. // 如果上级节点未被勾选,则让他半选
  217. if (!parentNode.checked) {
  218. parentNode.indeterminate = true
  219. }
  220. // 如果祖先节点未被勾选,则让他半选
  221. if (!forefathersNode.checked) {
  222. forefathersNode.indeterminate = true
  223. }
  224. // 如果当前节点是被取消勾选
  225. } else {
  226. const parentArr = []
  227. const forefathersArr = []
  228. const parentData = parentNode.data
  229. const forefathersData = forefathersNode.data
  230. let parentBool = true
  231. let forefathersBool = true
  232. // 筛选出所有兄弟key,如果有勾选的则代表上级不需要去除勾选
  233. if (parentData.children.length > 0) {
  234. parentData.children.forEach(parent => {
  235. parentArr.push(parent.dept_id)
  236. })
  237. for (let i of parentArr) {
  238. let thisNode = tree.getNode(i)
  239. if (thisNode.checked) {
  240. parentBool = false
  241. }
  242. }
  243. }
  244. // 为tree则代表没有三级节点被勾选,此时上级去除勾选
  245. if (parentBool) {
  246. parentNode.checked = false
  247. parentNode.indeterminate = false
  248. } else {
  249. parentNode.indeterminate = true
  250. }
  251. // 筛选出所有上级的兄弟key,如果有勾选的则代表上级不需要去除勾选
  252. if (forefathersData.children.length > 0) {
  253. forefathersData.children.forEach(parent => {
  254. forefathersArr.push(parent.dept_id)
  255. })
  256. for (let i of forefathersArr) {
  257. let thisNode = tree.getNode(i)
  258. if (thisNode.checked || thisNode.indeterminate) {
  259. forefathersBool = false
  260. }
  261. }
  262. }
  263. if (forefathersBool) {
  264. forefathersNode.indeterminate = false
  265. }
  266. }
  267. } catch (error) {
  268. console.warn(error)
  269. }
  270. },
  271. /**
  272. * 树被展开时
  273. * @param {Object} data 该节点的数据
  274. * @param {Object} node 节点对应的Node
  275. * @param {Object} ref 节点组件
  276. */
  277. handleTreeOpen(data, node) {
  278. // 如果节点被选中则不让展开
  279. if (node.checked) {
  280. Tip.warn('当前层级已被全选,无法展开!')
  281. node.expanded = false
  282. }
  283. },
  284. // 拼接出需要的树数据
  285. handleJoinTree() {
  286. try {
  287. const tree = this.$refs.tree
  288. const treeList = _.cloneDeep(this.treeList)
  289. // 被选中的节点
  290. const onItem = tree.getCheckedNodes()
  291. // 半选中的节点
  292. const halfItem = tree.getHalfCheckedNodes()
  293. const oneArr = []
  294. const twoArr = []
  295. const threeArr = []
  296. const oneArr_ = []
  297. const twoArr_ = []
  298. const threeArr_ = []
  299. // 节点分层
  300. if (onItem.length > 0) {
  301. onItem.forEach(item => {
  302. switch (item.depth) {
  303. case 1:
  304. oneArr.push(item.dept_id)
  305. break
  306. case 2:
  307. twoArr.push(item.dept_id)
  308. break
  309. case 3:
  310. threeArr.push(item.dept_id)
  311. break
  312. }
  313. })
  314. }
  315. if (halfItem.length > 0) {
  316. halfItem.forEach(item => {
  317. switch (item.depth) {
  318. case 1:
  319. oneArr_.push(item.dept_id)
  320. break
  321. case 2:
  322. twoArr_.push(item.dept_id)
  323. break
  324. case 3:
  325. threeArr_.push(item.dept_id)
  326. break
  327. }
  328. })
  329. }
  330. const oneList = this.handlejoinOne(treeList, oneArr, oneArr_)
  331. const twoList = this.handlejoinTwo(treeList, twoArr, twoArr_)
  332. const threeList = this.handlejoinThree(treeList, threeArr, threeArr_)
  333. // 将第二层拼进第一层
  334. oneList.forEach(item => {
  335. twoList.forEach(item2 => {
  336. if (item2.parent_id === item.dept_id) {
  337. if (!item.isOn) {
  338. item.children.push(item2)
  339. }
  340. }
  341. })
  342. })
  343. // 将第三层拼进第二层
  344. oneList.forEach(child1 => {
  345. if (child1.children.length > 0) {
  346. child1.children.forEach(child2 => {
  347. threeList.forEach(child3 => {
  348. if (child3.parent_id === child2.dept_id) {
  349. if (!child2.isOn) {
  350. child2.children.push(child3)
  351. }
  352. }
  353. })
  354. })
  355. }
  356. })
  357. return oneList
  358. } catch (error) {
  359. console.warn(error)
  360. }
  361. },
  362. // 返回第一层
  363. handlejoinOne(treeList, oneArr, oneArr_) {
  364. try {
  365. // 找出第一层节点
  366. const oneList = []
  367. treeList.forEach(item => {
  368. for (let i of oneArr) {
  369. if (item.dept_id === i) {
  370. oneList.push({
  371. dept_id: item.dept_id,
  372. children: [],
  373. isOn: true,
  374. name: item.dept_name
  375. })
  376. }
  377. }
  378. for (let i of oneArr_) {
  379. if (item.dept_id === i) {
  380. oneList.push({
  381. dept_id: item.dept_id,
  382. children: [],
  383. isOn: false,
  384. name: item.dept_name
  385. })
  386. }
  387. }
  388. })
  389. return oneList
  390. } catch (error) {
  391. console.warn(error)
  392. }
  393. },
  394. // 返回第二层
  395. handlejoinTwo(treeList, twoArr, twoArr_) {
  396. try {
  397. const twoList = []
  398. treeList.forEach(item => {
  399. if (item.children.length > 0) {
  400. item.children.forEach(item2 => {
  401. for (let i of twoArr) {
  402. if (item2.dept_id === i) {
  403. twoList.push({
  404. dept_id: item2.dept_id,
  405. children: [],
  406. isOn: true,
  407. parent_id: item2.parent_id,
  408. name: item2.dept_name
  409. })
  410. }
  411. }
  412. for (let i of twoArr_) {
  413. if (item2.dept_id === i) {
  414. twoList.push({
  415. dept_id: item2.dept_id,
  416. children: [],
  417. isOn: false,
  418. parent_id: item2.parent_id,
  419. name: item2.dept_name
  420. })
  421. }
  422. }
  423. })
  424. }
  425. })
  426. return twoList
  427. } catch (error) {
  428. console.warn(error)
  429. }
  430. },
  431. // 返回第三层
  432. handlejoinThree(treeList, threeArr, threeArr_) {
  433. try {
  434. const threeList = []
  435. treeList.forEach(item => {
  436. if (item.children.length > 0) {
  437. item.children.forEach(item2 => {
  438. if (item2.children.length > 0) {
  439. item2.children.forEach(item3 => {
  440. for (let i of threeArr) {
  441. if (item3.dept_id === i) {
  442. threeList.push({
  443. dept_id: item3.dept_id,
  444. isOn: true,
  445. parent_id: item3.parent_id,
  446. name: item3.dept_name
  447. })
  448. }
  449. }
  450. for (let i of threeArr_) {
  451. if (item3.dept_id === i) {
  452. threeList.push({
  453. dept_id: item3.dept_id,
  454. isOn: false,
  455. parent_id: item3.parent_id,
  456. name: item3.dept_name
  457. })
  458. }
  459. }
  460. })
  461. }
  462. })
  463. }
  464. })
  465. return threeList
  466. } catch (error) {
  467. console.warn(error)
  468. }
  469. },
  470. // 将数据的key恢复为原来的
  471. handleRestoreKey() {
  472. try {
  473. const treeList = this.handleJoinTree()
  474. // 去掉id后面的壹 贰 叁
  475. treeList.forEach(item1 => {
  476. item1.dept_id = item1.dept_id.replace('壹', '')
  477. if (item1.children.length > 0) {
  478. item1.children.forEach(item2 => {
  479. item2.dept_id = item2.dept_id.replace('贰', '')
  480. item2.parent_id = item2.parent_id.replace('壹', '')
  481. if (item2.children.length > 0) {
  482. item2.children.forEach(item3 => {
  483. item3.dept_id = item3.dept_id.replace('叁', '')
  484. item3.parent_id = item3.parent_id.replace('贰', '')
  485. })
  486. }
  487. })
  488. }
  489. })
  490. // 将dept_id字段转为proj_id将dept_name字段转为proj_name,将children转为projs
  491. treeList.forEach(child1 => {
  492. if (child1.children.length > 0) {
  493. const childObj = child1.children.map(item => {
  494. let returnObj = {}
  495. if (item.children.length > 0) {
  496. const obj = item.children
  497. obj.children = obj.map(child2 => {
  498. return {
  499. proj_id: child2.dept_id,
  500. proj_name: child2.name
  501. }
  502. })
  503. returnObj = {
  504. dept_id: item.dept_id,
  505. dept_name: item.name,
  506. projs: obj.children
  507. }
  508. } else {
  509. returnObj = {
  510. projs: [],
  511. dept_id: item.dept_id,
  512. isOn: true,
  513. name: item.name
  514. }
  515. }
  516. return returnObj
  517. })
  518. child1.children = childObj
  519. }
  520. })
  521. console.log(treeList)
  522. return treeList
  523. } catch (error) {
  524. console.warn(error)
  525. }
  526. },
  527. // 详情设置树勾选
  528. handleSetTree(list) {
  529. try {
  530. console.log(list)
  531. const one = []
  532. const two = []
  533. const three = []
  534. if (list.length > 0) {
  535. // 第一层
  536. list.forEach(item => {
  537. let child = item.children || ''
  538. let obj = { id: item.dept_id + '壹', isOn: true }
  539. if (child && child.length > 0) {
  540. obj.isOn = false
  541. }
  542. one.push(obj)
  543. })
  544. // 第二层
  545. list.forEach(item1 => {
  546. let child1 = item1.children || ''
  547. if (child1 && child1.length > 0) {
  548. child1.forEach(item2 => {
  549. let child2 = item2.projs || ''
  550. let obj = { id: item2.dept_id + '贰', isOn: true }
  551. if (child2 && child2.length > 0) {
  552. obj.isOn = false
  553. }
  554. two.push(obj)
  555. })
  556. }
  557. })
  558. // 第二层
  559. list.forEach(item1 => {
  560. let child1 = item1.children || ''
  561. if (child1 && child1.length > 0) {
  562. child1.forEach(item2 => {
  563. let child2 = item2.projs || ''
  564. if (child2 && child2.length > 0) {
  565. child2.forEach(item3 => {
  566. let obj = { id: item3.proj_id + '叁', isOn: true }
  567. three.push(obj)
  568. })
  569. }
  570. })
  571. }
  572. })
  573. const tree = this.$refs.tree
  574. // 勾选第一层
  575. if (one && one.length > 0) {
  576. one.forEach(item => {
  577. let node = tree.getNode(item.id)
  578. if (item.isOn) {
  579. node.checked = true
  580. this.handleOneNode(true, node.data)
  581. } else {
  582. node.indeterminate = true
  583. }
  584. })
  585. }
  586. // 勾选第二层
  587. if (two && two.length > 0) {
  588. two.forEach(item => {
  589. let node = tree.getNode(item.id)
  590. if (item.isOn) {
  591. node.checked = true
  592. this.handleTwoNode(true, node.data)
  593. } else {
  594. node.indeterminate = true
  595. }
  596. })
  597. }
  598. // 勾选第三层
  599. if (three && three.length > 0) {
  600. three.forEach(item => {
  601. let node = tree.getNode(item.id)
  602. node.checked = true
  603. })
  604. }
  605. }
  606. } catch (error) {
  607. console.warn(error)
  608. }
  609. }
  610. }

获取转换后的结构:

  1. this.treeList = this.handleChangeKey(data)

提交转换后的结构:

  1. const treeList = this.handleRestoreKey()

5,总结


如果你有用到Tree组件,且产品出的需求不咋地,可以看看Tree常用这些方法技巧;

  • 获取指定ID的节点:this.$refs.tree.getNode(id)

  • 返回目前半选中的节点所组成的数组:this.$refs.tree.getHalfCheckedNodes()

  • 返回目前被选中的节点所组成的数组:this.$refs.tree.getCheckedNodes()

  • 通过 key / data 设置某个节点的勾选状态:this.$refs.tree.setChecked(id, true)


如果看了觉得有帮助的,我是@鹏多多,欢迎 点赞 关注 评论;END


PS:在本页按F12,在console中输入document.querySelectorAll('.diggit')[0].click(),有惊喜哦


公众号

往期文章

个人主页

element-ui的Tree树组件使用技巧的更多相关文章

  1. Tree( 树) 组件[4]

    本节课重点了解 EasyUI 中 Tree(树)组件的使用方法, 这个组件依赖于 Draggable(拖动)和 Droppable(放置)组件.一.方法列表 //部分方法onClick : funct ...

  2. Tree( 树) 组件[3]

    本节课重点了解 EasyUI 中 Tree(树)组件的使用方法, 这个组件依赖于 Draggable(拖动)和 Droppable(放置)组件.一. 事件列表很多事件的回调函数都包含'node'参数, ...

  3. Tree( 树) 组件[2]

    本节课重点了解 EasyUI 中 Tree(树)组件的使用方法, 这个组件依赖于 Draggable(拖动)和 Droppable(放置)组件.一. 异步加载如果想从数据库里获取导航内容, 那么就必须 ...

  4. Tree( 树) 组件[1]

    本节课重点了解 EasyUI 中 Tree(树)组件的使用方法, 这个组件依赖于 Draggable(拖动)和 Droppable(放置)组件. 一. 加载方式//class 加载方式<ul c ...

  5. 第二百二十六节,jQuery EasyUI,Tree(树)组件

    jQuery EasyUI,Tree(树)组件 本节课重点了解 EasyUI 中 Tree(树)组件的使用方法,这个组件依赖于 Draggable(拖 动)和 Droppable(放置)组件. 一.加 ...

  6. JQuery Easy Ui (Tree树)详解(转)

    第一讲:JQuery Easy Ui到底是什么呢? 首先咱们知道JQuery是对Java Script的封装,是一个js库,主要提供的功能是选择器,属性修改和事件绑定等等.. JQuery ui是在j ...

  7. Element ui 上传文件组件(单文件上传) 点击提交 没反应

    element ui 第一次上传文件后 上传其他文件再次点击不再次提交 需要使用 clearFiles 清空已上传文件列表 这时候在次点击 上传按钮 就会惊喜的发现 可以上传了使用方法 this.$r ...

  8. EasyUI - Tree 树组件

    效果: 数据库设计: 使用的数据: 其中的字段,是跟据要生成的树节点的属性定义的. text:代表要显示的字段名称. state:是否是目录节点. iconCls:节点的图标是什么. url:跳转的链 ...

  9. 基于element ui的级联选择器组件实现的分类后台接口

    今天在做资产管理系统的时候遇到一个分类的级联选择器,前端是用的element的组件,需要后台提供接口支持.     这个组件需要传入的数据结构大概是这样的,详细的可参考官方案例: [{ value: ...

随机推荐

  1. 【Openxml】将Openxml的椭圆弧线arcTo转为Svg的椭圆弧线

    本文将介绍如何将OpenXml的actTo转为Svg的弧线(a) OpenXml的artTo 首先下面是一段OpenXml的arcTo弧线 <arcTo wR="152403" ...

  2. 2018秋招C/C++面试题总结

    一.C和C++的区别是什么? C是面向过程的语言,C++是在C语言的基础上开发的一种面向对象编程语言,应用广泛.C中函数不能进行重载,C++函数可以重载C++在C的基础上增添类,C是一个结构化语言,它 ...

  3. 异步编程之EAP

    一.概述 前面我们了解到了APM编程模式,但APM不支持对异步操作的取消和没有提供对进度报告的功能. 对于界面程序来说,进度报告和取消操作的支持也是必不可少的,为了支持这些功能,微软在.NET 2.0 ...

  4. react项目实现多语言切换

    网站的语言切换功能大家都见过不少,一般都是一个下拉框选择语言,如果让我们想一下怎么实现这个功能,我相信大家都是有哥大概思路,一个语言切换的select,将当前的选择的语言存在全局,根据这个语言的key ...

  5. mybatis gengeator一键生成

  6. excel快捷键如下:

    ALT+ 空格键,然后按下 X ALT+ 空格键,然后按下 R  首先打开表格,在A1对角用鼠标左键单击,界面会全部选中,然后调整字体大小框里的数字,回车,表格就变大了. 同时按Alt和E,再按L   ...

  7. K8S最小硬件配置

  8. shell循环语句for

    1.方式1 for i in {list[0]} {list[1]} .. do 执行命令 done 2.方式2(三要素循环) for (( 初始值; 判断值; 步长; )) do 执行命令 done

  9. Git - Mac 电脑使用 brew 更新 Git

    安装 Homebrew Homebrew 是一个软件包管理器.它的作用就是将软件包安装到自己的目录中,然后将其文件符号链接到 /usr/local.更多信息,请自行进入官网查看 https://bre ...

  10. 两种方式配置vue全局方法

    目录 1,前言 2,第一种方式 3,第二种方式 1,前言 在Vue项目开发中,肯定会有这样一个场景:在不同的组件页面用到同样的方法,比如格式化时间,文件下载,对象深拷贝,返回数据类型,复制文本等等.这 ...