tree-node.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <template>
  2. <div class="el-tree-node"
  3. @click.stop="handleClick"
  4. :class="{ expanded: childNodeRendered && expanded, 'is-current': $tree.currentNode === _self }">
  5. <div class="el-tree-node__content"
  6. :style="{ 'padding-left': node.level * 16 + 'px' }"
  7. @click="handleExpandIconClick">
  8. <span
  9. class="el-tree-node__expand-icon"
  10. :class="{ 'is-leaf': node.isLeaf, expanded: !node.isLeaf && expanded }">
  11. </span>
  12. <el-checkbox
  13. v-if="showCheckbox"
  14. v-model="node.checked"
  15. :indeterminate="node.indeterminate"
  16. @change="handleCheckChange"
  17. @click.native="handleUserClick">
  18. </el-checkbox>
  19. <span
  20. v-if="node.loading"
  21. class="el-tree-node__icon el-icon-loading">
  22. </span>
  23. <node-content :node="node"></node-content>
  24. </div>
  25. <collapse-transition>
  26. <div
  27. class="el-tree-node__children"
  28. v-show="expanded">
  29. <el-tree-node
  30. :render-content="renderContent"
  31. v-for="child in node.childNodes"
  32. :node="child">
  33. </el-tree-node>
  34. </div>
  35. </collapse-transition>
  36. </div>
  37. </template>
  38. <script type="text/jsx">
  39. import CollapseTransition from './transition';
  40. export default {
  41. name: 'el-tree-node',
  42. props: {
  43. node: {
  44. default() {
  45. return {};
  46. }
  47. },
  48. props: {},
  49. renderContent: Function
  50. },
  51. components: {
  52. CollapseTransition,
  53. NodeContent: {
  54. props: {
  55. node: {
  56. required: true
  57. }
  58. },
  59. render(h) {
  60. const parent = this.$parent;
  61. return (
  62. parent.renderContent
  63. ? parent.renderContent.call(parent._renderProxy, h, { _self: parent.$parent.$vnode.context, node: this.node })
  64. : <span class="el-tree-node__label">{ this.node.label }</span>
  65. );
  66. }
  67. }
  68. },
  69. data() {
  70. return {
  71. $tree: null,
  72. expanded: false,
  73. childNodeRendered: false,
  74. showCheckbox: false,
  75. oldChecked: null,
  76. oldIndeterminate: null
  77. };
  78. },
  79. watch: {
  80. 'node.indeterminate'(val) {
  81. this.handleSelectChange(this.node.checked, val);
  82. },
  83. 'node.checked'(val) {
  84. this.handleSelectChange(val, this.node.indeterminate);
  85. }
  86. },
  87. methods: {
  88. handleSelectChange(checked, indeterminate) {
  89. if (this.oldChecked !== checked && this.oldIndeterminate !== indeterminate) {
  90. this.$tree.$emit('check-change', this.node.data, checked, indeterminate);
  91. }
  92. this.oldChecked = checked;
  93. this.indeterminate = indeterminate;
  94. },
  95. handleClick() {
  96. this.$tree.currentNode = this;
  97. },
  98. handleExpandIconClick(event) {
  99. let target = event.target;
  100. if (target.tagName.toUpperCase() !== 'DIV' &&
  101. target.parentNode.nodeName.toUpperCase() !== 'DIV' ||
  102. target.nodeName.toUpperCase() === 'LABEL') return;
  103. if (this.expanded) {
  104. this.node.collapse();
  105. this.expanded = false;
  106. } else {
  107. this.node.expand(() => {
  108. this.expanded = true;
  109. this.childNodeRendered = true;
  110. });
  111. }
  112. this.$tree.$emit('node-click', this.node.data, this.node, this);
  113. },
  114. handleUserClick() {
  115. if (this.node.indeterminate) {
  116. this.node.setChecked(this.node.checked, true);
  117. }
  118. },
  119. handleCheckChange(ev) {
  120. if (!this.node.indeterminate) {
  121. this.node.setChecked(ev.target.checked, true);
  122. }
  123. }
  124. },
  125. created() {
  126. var parent = this.$parent;
  127. if (parent.$isTree) {
  128. this.$tree = parent;
  129. } else {
  130. this.$tree = parent.$tree;
  131. }
  132. const tree = this.$tree;
  133. const props = this.props || {};
  134. const childrenKey = props['children'] || 'children';
  135. this.$watch(`node.data.${childrenKey}`, () => {
  136. this.node.updateChildren();
  137. });
  138. if (!tree) {
  139. console.warn('Can not find node\'s tree.');
  140. }
  141. this.showCheckbox = tree.showCheckbox;
  142. }
  143. };
  144. </script>