tree2.mjs 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. import { defineComponent, ref, getCurrentInstance, computed, watch, provide, resolveComponent, openBlock, createElementBlock, normalizeClass, Fragment, renderList, createBlock, renderSlot, createElementVNode, toDisplayString, createCommentVNode, withDirectives, vShow } from 'vue';
  2. import { isEqual } from 'lodash-unified';
  3. import TreeStore from './model/tree-store.mjs';
  4. import { getNodeKey, handleCurrentChange } from './model/util.mjs';
  5. import ElTreeNode from './tree-node.mjs';
  6. import { useNodeExpandEventBroadcast } from './model/useNodeExpandEventBroadcast.mjs';
  7. import { useDragNodeHandler } from './model/useDragNode.mjs';
  8. import { useKeydown } from './model/useKeydown.mjs';
  9. import { ROOT_TREE_INJECTION_KEY } from './tokens.mjs';
  10. import { treeProps, treeEmits } from './tree.mjs';
  11. import _export_sfc from '../../../_virtual/plugin-vue_export-helper.mjs';
  12. import { useLocale } from '../../../hooks/use-locale/index.mjs';
  13. import { useNamespace } from '../../../hooks/use-namespace/index.mjs';
  14. import { formItemContextKey } from '../../form/src/constants.mjs';
  15. const _sfc_main = defineComponent({
  16. name: "ElTree",
  17. components: { ElTreeNode },
  18. props: treeProps,
  19. emits: treeEmits,
  20. setup(props, ctx) {
  21. const { t } = useLocale();
  22. const ns = useNamespace("tree");
  23. const store = ref(
  24. new TreeStore({
  25. key: props.nodeKey,
  26. data: props.data,
  27. lazy: props.lazy,
  28. props: props.props,
  29. load: props.load,
  30. currentNodeKey: props.currentNodeKey,
  31. checkStrictly: props.checkStrictly,
  32. checkDescendants: props.checkDescendants,
  33. defaultCheckedKeys: props.defaultCheckedKeys,
  34. defaultExpandedKeys: props.defaultExpandedKeys,
  35. autoExpandParent: props.autoExpandParent,
  36. defaultExpandAll: props.defaultExpandAll,
  37. filterNodeMethod: props.filterNodeMethod
  38. })
  39. );
  40. store.value.initialize();
  41. const root = ref(store.value.root);
  42. const currentNode = ref(null);
  43. const el$ = ref(null);
  44. const dropIndicator$ = ref(null);
  45. const { broadcastExpanded } = useNodeExpandEventBroadcast(props);
  46. const { dragState } = useDragNodeHandler({
  47. props,
  48. ctx,
  49. el$,
  50. dropIndicator$,
  51. store
  52. });
  53. useKeydown({ el$ }, store);
  54. const instance = getCurrentInstance();
  55. const isSelectTree = computed(() => {
  56. let parent = instance == null ? void 0 : instance.parent;
  57. while (parent) {
  58. if (parent.type.name === "ElTreeSelect") {
  59. return true;
  60. }
  61. parent = parent.parent;
  62. }
  63. return false;
  64. });
  65. const isEmpty = computed(() => {
  66. const { childNodes } = root.value;
  67. return (!childNodes || childNodes.length === 0 || childNodes.every(({ visible }) => !visible)) && !isSelectTree.value;
  68. });
  69. watch(
  70. () => props.currentNodeKey,
  71. (newVal) => {
  72. store.value.setCurrentNodeKey(newVal != null ? newVal : null);
  73. }
  74. );
  75. watch(
  76. () => props.defaultCheckedKeys,
  77. (newVal, oldVal) => {
  78. if (isEqual(newVal, oldVal))
  79. return;
  80. store.value.setDefaultCheckedKey(newVal != null ? newVal : []);
  81. }
  82. );
  83. watch(
  84. () => props.defaultExpandedKeys,
  85. (newVal) => {
  86. store.value.setDefaultExpandedKeys(newVal != null ? newVal : []);
  87. }
  88. );
  89. watch(
  90. () => props.data,
  91. (newVal) => {
  92. store.value.setData(newVal);
  93. },
  94. { deep: true }
  95. );
  96. watch(
  97. () => props.checkStrictly,
  98. (newVal) => {
  99. store.value.checkStrictly = newVal;
  100. }
  101. );
  102. const filter = (value) => {
  103. if (!props.filterNodeMethod)
  104. throw new Error("[Tree] filterNodeMethod is required when filter");
  105. store.value.filter(value);
  106. };
  107. const getNodeKey$1 = (node) => {
  108. return getNodeKey(props.nodeKey, node.data);
  109. };
  110. const requireNodeKey = (methodName) => {
  111. if (!props.nodeKey) {
  112. throw new Error(`[Tree] nodeKey is required in ${methodName}`);
  113. }
  114. };
  115. const getNodePath = (data) => {
  116. requireNodeKey("getNodePath");
  117. const node = store.value.getNode(data);
  118. if (!node)
  119. return [];
  120. const path = [node.data];
  121. let parent = node.parent;
  122. while (parent && parent !== root.value) {
  123. path.push(parent.data);
  124. parent = parent.parent;
  125. }
  126. return path.reverse();
  127. };
  128. const getCheckedNodes = (leafOnly, includeHalfChecked) => {
  129. return store.value.getCheckedNodes(leafOnly, includeHalfChecked);
  130. };
  131. const getCheckedKeys = (leafOnly) => {
  132. return store.value.getCheckedKeys(leafOnly);
  133. };
  134. const getCurrentNode = () => {
  135. const currentNode2 = store.value.getCurrentNode();
  136. return currentNode2 ? currentNode2.data : null;
  137. };
  138. const getCurrentKey = () => {
  139. requireNodeKey("getCurrentKey");
  140. const currentNode2 = getCurrentNode();
  141. return currentNode2 ? currentNode2[props.nodeKey] : null;
  142. };
  143. const setCheckedNodes = (nodes, leafOnly) => {
  144. requireNodeKey("setCheckedNodes");
  145. store.value.setCheckedNodes(nodes, leafOnly);
  146. };
  147. const setCheckedKeys = (keys, leafOnly) => {
  148. requireNodeKey("setCheckedKeys");
  149. store.value.setCheckedKeys(keys, leafOnly);
  150. };
  151. const setChecked = (data, checked, deep) => {
  152. store.value.setChecked(data, checked, deep);
  153. };
  154. const getHalfCheckedNodes = () => {
  155. return store.value.getHalfCheckedNodes();
  156. };
  157. const getHalfCheckedKeys = () => {
  158. return store.value.getHalfCheckedKeys();
  159. };
  160. const setCurrentNode = (node, shouldAutoExpandParent = true) => {
  161. requireNodeKey("setCurrentNode");
  162. handleCurrentChange(store, ctx.emit, () => {
  163. broadcastExpanded(node);
  164. store.value.setUserCurrentNode(node, shouldAutoExpandParent);
  165. });
  166. };
  167. const setCurrentKey = (key = null, shouldAutoExpandParent = true) => {
  168. requireNodeKey("setCurrentKey");
  169. handleCurrentChange(store, ctx.emit, () => {
  170. broadcastExpanded();
  171. store.value.setCurrentNodeKey(key, shouldAutoExpandParent);
  172. });
  173. };
  174. const getNode = (data) => {
  175. return store.value.getNode(data);
  176. };
  177. const remove = (data) => {
  178. store.value.remove(data);
  179. };
  180. const append = (data, parentNode) => {
  181. store.value.append(data, parentNode);
  182. };
  183. const insertBefore = (data, refNode) => {
  184. store.value.insertBefore(data, refNode);
  185. };
  186. const insertAfter = (data, refNode) => {
  187. store.value.insertAfter(data, refNode);
  188. };
  189. const handleNodeExpand = (nodeData, node, instance2) => {
  190. broadcastExpanded(node);
  191. ctx.emit("node-expand", nodeData, node, instance2);
  192. };
  193. const updateKeyChildren = (key, data) => {
  194. requireNodeKey("updateKeyChild");
  195. store.value.updateChildren(key, data);
  196. };
  197. provide(ROOT_TREE_INJECTION_KEY, {
  198. ctx,
  199. props,
  200. store,
  201. root,
  202. currentNode,
  203. instance
  204. });
  205. provide(formItemContextKey, void 0);
  206. return {
  207. ns,
  208. store,
  209. root,
  210. currentNode,
  211. dragState,
  212. el$,
  213. dropIndicator$,
  214. isEmpty,
  215. filter,
  216. getNodeKey: getNodeKey$1,
  217. getNodePath,
  218. getCheckedNodes,
  219. getCheckedKeys,
  220. getCurrentNode,
  221. getCurrentKey,
  222. setCheckedNodes,
  223. setCheckedKeys,
  224. setChecked,
  225. getHalfCheckedNodes,
  226. getHalfCheckedKeys,
  227. setCurrentNode,
  228. setCurrentKey,
  229. t,
  230. getNode,
  231. remove,
  232. append,
  233. insertBefore,
  234. insertAfter,
  235. handleNodeExpand,
  236. updateKeyChildren
  237. };
  238. }
  239. });
  240. function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
  241. const _component_el_tree_node = resolveComponent("el-tree-node");
  242. return openBlock(), createElementBlock(
  243. "div",
  244. {
  245. ref: "el$",
  246. class: normalizeClass([
  247. _ctx.ns.b(),
  248. _ctx.ns.is("dragging", !!_ctx.dragState.draggingNode),
  249. _ctx.ns.is("drop-not-allow", !_ctx.dragState.allowDrop),
  250. _ctx.ns.is("drop-inner", _ctx.dragState.dropType === "inner"),
  251. { [_ctx.ns.m("highlight-current")]: _ctx.highlightCurrent }
  252. ]),
  253. role: "tree"
  254. },
  255. [
  256. (openBlock(true), createElementBlock(
  257. Fragment,
  258. null,
  259. renderList(_ctx.root.childNodes, (child) => {
  260. return openBlock(), createBlock(_component_el_tree_node, {
  261. key: _ctx.getNodeKey(child),
  262. node: child,
  263. props: _ctx.props,
  264. accordion: _ctx.accordion,
  265. "render-after-expand": _ctx.renderAfterExpand,
  266. "show-checkbox": _ctx.showCheckbox,
  267. "render-content": _ctx.renderContent,
  268. onNodeExpand: _ctx.handleNodeExpand
  269. }, null, 8, ["node", "props", "accordion", "render-after-expand", "show-checkbox", "render-content", "onNodeExpand"]);
  270. }),
  271. 128
  272. )),
  273. _ctx.isEmpty ? (openBlock(), createElementBlock(
  274. "div",
  275. {
  276. key: 0,
  277. class: normalizeClass(_ctx.ns.e("empty-block"))
  278. },
  279. [
  280. renderSlot(_ctx.$slots, "empty", {}, () => {
  281. var _a;
  282. return [
  283. createElementVNode(
  284. "span",
  285. {
  286. class: normalizeClass(_ctx.ns.e("empty-text"))
  287. },
  288. toDisplayString((_a = _ctx.emptyText) != null ? _a : _ctx.t("el.tree.emptyText")),
  289. 3
  290. )
  291. ];
  292. })
  293. ],
  294. 2
  295. )) : createCommentVNode("v-if", true),
  296. withDirectives(createElementVNode(
  297. "div",
  298. {
  299. ref: "dropIndicator$",
  300. class: normalizeClass(_ctx.ns.e("drop-indicator"))
  301. },
  302. null,
  303. 2
  304. ), [
  305. [vShow, _ctx.dragState.showDropIndicator]
  306. ])
  307. ],
  308. 2
  309. );
  310. }
  311. var Tree = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__file", "/home/runner/work/element-plus/element-plus/packages/components/tree/src/tree.vue"]]);
  312. export { Tree as default };
  313. //# sourceMappingURL=tree2.mjs.map