..._树形控件懒加载自定义节点中使用v-if">
当前位置:   article > 正文

element-ui树形组件实现懒加载、右键新增、右键删除、右键编辑,以及拖拽更换节点_树形控件懒加载自定义节点中使用v-if

树形控件懒加载自定义节点中使用v-if

  1. <template>
  2. <el-card shadow="never" class="aui-card--fill">
  3. <div class="tree-box">
  4. <div class="tree-title">
  5. <el-input placeholder="输入关键字进行过滤" v-model.trim="tree.filterText" size="small"></el-input>
  6. </div>
  7. <div class="tree-content" v-loading="tree.loading">
  8. <div v-if="position=='page'" style="position:relative">
  9. <span style="position:absolute;z-index:2;top:6px;right:3px;font-size:12px;color:#9c9b9b">(右键可编辑视频树形分类)</span>
  10. </div>
  11. <el-tree
  12. class="filter-tree"
  13. :load="loadNode"
  14. lazy
  15. :draggable="$hasPermission('video:video-manage:dragclass')"
  16. @node-expand="handleNodeExpand"
  17. @node-collapse="handleNodeCollapse"
  18. :default-expanded-keys="tree.expandedKeys"
  19. node-key="id"
  20. :highlight-current="highlightCurrent"
  21. :props="tree.defaultProps"
  22. :expand-on-click-node="false"
  23. :filter-node-method="filterNode"
  24. @node-click="hadleNodeClick"
  25. @node-contextmenu="rihgtClick"
  26. @node-drop="handleDrop"
  27. :allow-drop="allowDrop"
  28. :allow-drag="allowDrag"
  29. ref="tree"
  30. ></el-tree>
  31. <div v-show="menuVisible" id="rightClickMenu">
  32. <ul class="menu-list">
  33. <li>
  34. <el-button
  35. type="text"
  36. size="small"
  37. @click="NodeConfig('add')"
  38. v-if="$hasPermission('video:video-manage:addclass')"
  39. >新增子分类</el-button>
  40. </li>
  41. <li>
  42. <el-button
  43. type="text"
  44. size="small"
  45. :disabled="DATA&&DATA.id=='1270550715957256193'"
  46. @click="NodeDel()"
  47. v-if="$hasPermission('video:video-manage:deleteclass')"
  48. >删除分类</el-button>
  49. </li>
  50. <li>
  51. <el-button
  52. type="text"
  53. size="small"
  54. :disabled="DATA&&DATA.id=='1270550715957256193'"
  55. @click="NodeConfig('edit')"
  56. v-if="$hasPermission('video:video-manage:editclass')"
  57. >编辑分类</el-button>
  58. </li>
  59. </ul>
  60. </div>
  61. </div>
  62. </div>
  63. <videoConfig ref="videoConfig" @updateTree="updateTree" />
  64. </el-card>
  65. </template>
  66. <script>
  67. import videoConfig from "@/components/video/model-videoClass-config";
  68. import debounce from "lodash/debounce";
  69. export default {
  70. name: "",
  71. components: {
  72. videoConfig,
  73. },
  74. props: {
  75. currentKey: {
  76. type: String,
  77. default: "",
  78. },
  79. position: {
  80. type: String,
  81. default: "page",
  82. },
  83. isSelect: {
  84. type: Boolean,
  85. default: false,
  86. },
  87. },
  88. data() {
  89. return {
  90. configType: "",
  91. menuVisible: false,
  92. objectID: "",
  93. DATA: null,
  94. VALUE: null,
  95. highlightCurrent: true,
  96. tree: {
  97. data: [],
  98. expandedKeys: ['1270550715957256193'],/**设置默认展开的节点,此时必须设置node-key,其值为节点数据中的一个字段名,该字段在整棵树中是唯一的。 */
  99. node: null,
  100. resolve: null,
  101. loading: false,
  102. filterText: "",
  103. defaultProps: {
  104. children: "children",
  105. label: "name",
  106. isLeaf: "isLeaf",
  107. },
  108. },
  109. };
  110. },
  111. watch: {
  112. "tree.filterText"(val) {
  113. this.$refs.tree.filter(val);
  114. },
  115. },
  116. computed: {
  117. dataRule() {
  118. return {
  119. name: [
  120. {
  121. required: true,
  122. message: this.$t("validate.required"),
  123. trigger: "blur",
  124. },
  125. ],
  126. };
  127. },
  128. enabledConfig() {
  129. return (
  130. this.$hasPermission("video:video-manage:addclass") ||
  131. this.$hasPermission("video:video-manage:editclass") ||
  132. this.$hasPermission("video:video-manage:deleteclass")
  133. );
  134. },
  135. },
  136. created() {},
  137. mounted() {},
  138. methods: {
  139. //懒加载
  140. async loadNode(node, resolve) {
  141. if (node.level === 0) {
  142. this.tree.node = node;
  143. this.tree.resolve = resolve;
  144. let rootData = [
  145. { id: "1270550715957256193", name: "视频分类", parentId: null ,children:[]},
  146. ];
  147. this.tree.expandedKeys = [rootData[0].id];
  148. resolve(rootData);
  149. this.$nextTick(() => {
  150. this.$refs["tree"].setCurrentKey("1270550715957256193");
  151. this.$emit("updateTreeItem", rootData[0]);
  152. });
  153. } else {
  154. let ndoeData = await this.loadTreeData(node.data.id);
  155. resolve(ndoeData);
  156. }
  157. if (this.currentKey) {
  158. this.reShowHighlight();
  159. }
  160. },
  161. //高亮其中一项
  162. reShowHighlight() {
  163. this.$nextTick(() => {
  164. this.$refs.tree.setCurrentKey(this.currentKey);
  165. });
  166. },
  167. //加载树形数据
  168. loadTreeData(parentId) {
  169. return new Promise((resolve, reject) => {
  170. this.$http
  171. .get("/vod/mrcategory/list", {
  172. params: {
  173. parentId: parentId,
  174. selectChildList: 0,
  175. },
  176. })
  177. .then(({ data: res }) => {
  178. resolve(res.data);
  179. })
  180. .catch((er) => {
  181. reject(er);
  182. });
  183. });
  184. },
  185. // 搜索
  186. filterNode(value, data) {
  187. if (!value) return true;
  188. return data.name.indexOf(value) !== -1;
  189. },
  190. // 右击
  191. rihgtClick(event, object, node, element) {
  192. if (
  193. this.position === "modal" ||
  194. !(
  195. this.$hasPermission("video:video-manage:addclass") ||
  196. this.$hasPermission("video:video-manage:editclass") ||
  197. this.$hasPermission("video:video-manage:deleteclass")
  198. )
  199. ) {
  200. return;
  201. }
  202. if (this.objectID !== object.id) {
  203. this.objectID = object.id;
  204. this.menuVisible = true;
  205. this.DATA = object;//该节点所对应的对象
  206. this.NODE = node;//该节点所对应的node
  207. const parent = this.NODE.parent;
  208. // this.$refs.tree.append(({ name: this.dataForm.name }, object));
  209. } else {
  210. this.menuVisible = !this.menuVisible;
  211. }
  212. document.addEventListener("click", (e) => {
  213. this.menuVisible = false;
  214. });
  215. let menu = document.querySelector("#rightClickMenu");
  216. /* 菜单定位基于鼠标点击位置 */
  217. menu.style.left = event.offsetX + 50 + "px";
  218. menu.style.top = event.offsetY + 50 + "px";
  219. // menu.style.left = event.clientX + 30 + "px";
  220. // menu.style.top = event.clientY + 30 + "px";
  221. },
  222. // 点击树的item
  223. hadleNodeClick(data, node) {
  224. this.menuVisible = false;
  225. if (
  226. this.position == "modal" &&
  227. data.name == "视频分类" &&
  228. this.isSelect
  229. ) {
  230. this.highlightCurrent = false;
  231. this.$emit("updateTreeItem", {
  232. id: "",
  233. name: "",
  234. parentId: null,
  235. });
  236. } else {
  237. this.highlightCurrent = true;
  238. this.$emit("updateTreeItem", data);
  239. }
  240. },
  241. // 树展开某一节点的时候
  242. handleNodeExpand(data, node, ele) {
  243. this.$set(ele, "expanded", true);
  244. if (node.expanded) {
  245. this.tree.expandedKeys.push(data.id);
  246. this.tree.expandedKeys = Array.from(new Set(this.tree.expandedKeys));//去重
  247. }
  248. },
  249. // 树关闭某一节点的时候
  250. handleNodeCollapse(data, node, ele) {
  251. let index = this.tree.expandedKeys.findIndex((item) => item === data.id);
  252. if (index !== -1) {
  253. this.tree.expandedKeys.splice(index, 1);
  254. }
  255. this.$set(ele, "expanded", false);//需要手动折叠当前节点
  256. },
  257. NodeConfig(type) {
  258. this.configType = type;
  259. if (type === "add") {
  260. this.$refs.videoConfig.initModal({ parentId: this.DATA.id });
  261. } else {
  262. let data = JSON.parse(JSON.stringify(this.DATA));
  263. this.$refs.videoConfig.initModal(data);
  264. }
  265. },
  266. //新增或者编辑的回调
  267. updateTree(data) {
  268. if (this.configType === "edit") {
  269. this.$set(this.DATA, "name", data.name);
  270. } else {
  271. if (!this.DATA.children) {
  272. this.$set(this.DATA, "children", []);
  273. }
  274. this.$nextTick(() => {
  275. this.DATA.children.push(data);
  276. });
  277. }
  278. },
  279. //删除
  280. NodeDel() {
  281. this.$confirm(
  282. this.$t("prompt.info", { handle: this.$t("delete") }),
  283. this.$t("prompt.title"),
  284. {
  285. confirmButtonText: this.$t("confirm"),
  286. cancelButtonText: this.$t("cancel"),
  287. type: "warning",
  288. }
  289. )
  290. .then(() => {
  291. this.$http
  292. .delete("/vod/mrcategory", {
  293. data: [this.DATA.id],
  294. })
  295. .then(({ data: res }) => {
  296. if (res.code !== 0) {
  297. return this.$message.error(res.msg);
  298. }
  299. this.$message({
  300. message: this.$t("prompt.success"),
  301. type: "success",
  302. duration: 500,
  303. onClose: () => {
  304. // let node = this.$refs.tree.getNode(this.DATA.parentId);
  305. // node.loaded = false;
  306. // node.expand();
  307. // const parent = this.NODE.parent;
  308. // const children = parent.data.children || parent.data;
  309. // const index = children.findIndex(d => d.id === this.DATA.id);
  310. // children.splice(index, 1);
  311. this.$refs.tree.remove(this.NODE);
  312. },
  313. });
  314. })
  315. .catch(() => {});
  316. })
  317. .catch(() => {});
  318. },
  319. //拖拽执行的更新方法
  320. handleDrop(draggingNode, dropNode, dropType, ev) {
  321. this.$http["put"]("/vod/mrcategory", {
  322. name: draggingNode.data.name,
  323. id: draggingNode.data.id,
  324. parentId:
  325. dropType === "inner" ? dropNode.data.id : dropNode.data.parentId,
  326. })
  327. .then(({ data: res }) => {
  328. if (res.code !== 0) {
  329. return this.$message.error(res.msg);
  330. }
  331. this.$message({
  332. message: this.$t("prompt.success"),
  333. type: "success",
  334. duration: 500,
  335. onClose: () => {},
  336. });
  337. })
  338. .catch(() => {});
  339. },
  340. //允许被扔放的节点
  341. allowDrop(draggingNode, dropNode, type) {
  342. return dropNode.data.id !== "1270550715957256193";
  343. // if (dropNode.data.id === "1270550715957256193") {
  344. // return type !== "before";
  345. // } else {
  346. // return true;
  347. // }
  348. },
  349. //允许拖拽的节点
  350. allowDrag(draggingNode) {
  351. return draggingNode.data.id !== "1270550715957256193";
  352. },
  353. },
  354. destroyed() {},
  355. };
  356. </script>
  357. <style lang='scss'>
  358. #video-manage {
  359. .el-tree__empty-block{
  360. margin-top: 100px;
  361. }
  362. .tree-box {
  363. .tree-title {
  364. margin-bottom: 10px;
  365. }
  366. .tree-content {
  367. height: calc(100vh - 50px - 38px - 30px - 40px - 42px);
  368. overflow: auto;
  369. &::-webkit-scrollbar {
  370. width: 6px;
  371. height: 6px;
  372. }
  373. &::-webkit-scrollbar-track {
  374. background: #f1f1f1;
  375. border-radius: 8px;
  376. }
  377. &::-webkit-scrollbar-track-piece {
  378. /*内层轨道,滚动条中间部分(位置4)*/
  379. border-radius: 2px 2px 0px 0px;
  380. }
  381. &::-webkit-scrollbar-thumb {
  382. background: #c1c1c1;
  383. border-radius: 6px;
  384. }
  385. &::-webkit-scrollbar-thumb:hover {
  386. background: #aba8a8;
  387. }
  388. &::-webkit-scrollbar-corner {
  389. background: #f6f6f6;
  390. }
  391. #rightClickMenu {
  392. background: #fff;
  393. position: absolute;
  394. z-index: 3;
  395. transform-origin: left center;
  396. width: 100px;
  397. height: 150px;
  398. padding: 10px;
  399. border-radius: 5px;
  400. box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  401. ul {
  402. li {
  403. .el-button {
  404. width: 100%;
  405. text-align: left;
  406. }
  407. }
  408. }
  409. }
  410. }
  411. }
  412. }
  413. </style>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/119209
推荐阅读
相关标签