TreeView.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. <template>
  2. <div
  3. class="he_tree_content he_tree_view"
  4. style="font-size: 14px"
  5. v-loading="loading"
  6. >
  7. <el-tree
  8. :data="treeData"
  9. :props="defaultProps"
  10. @node-click="handleNodeClick"
  11. >
  12. <div class="custom-tree-node" slot-scope="{ node }">
  13. <div>
  14. <span style="margin-right: 10px">{{ node.label }}</span>
  15. </div>
  16. </div></el-tree
  17. >
  18. <!-- <Tree :draggable="draggable" :value="treeData" ref="tree">
  19. <div
  20. :style="{
  21. paddingLeft:
  22. node.is_courseware === 'false'
  23. ? node.nodexIndex * 22 + 8 + 'px'
  24. : '0px',
  25. }"
  26. class="tree_box"
  27. slot-scope="{ node, path, tree }"
  28. >
  29. <span
  30. @click="tree.toggleFold(node, path)"
  31. class="el-icon_box"
  32. v-if="node.is_courseware === 'false'"
  33. >
  34. <template
  35. v-if="
  36. node.children && node.children.length > 0 && node.$folded == true
  37. "
  38. >
  39. <img src="../../../assets/common/icon-tree-arrow-right.png" />
  40. </template>
  41. <template
  42. v-else-if="
  43. node.children && node.children.length > 0 && node.$folded == false
  44. "
  45. >
  46. <img src="../../../assets/common/icon-tree-arrow-bottom.png" />
  47. </template>
  48. </span>
  49. <span
  50. :class="[
  51. 'tree_box_item',
  52. 'tree_box_' + node.nodexIndex,
  53. activeIndex !== '' && JSON.stringify(node).indexOf(activeIndex) > -1
  54. ? 'tree_box_item_light'
  55. : '',
  56. ]"
  57. @click="tree.toggleFold(node, path)"
  58. v-if="node.is_courseware === 'false'"
  59. :title="node.name"
  60. >
  61. {{ node.name }}
  62. </span>
  63. <span
  64. :class="[
  65. 'tree_box_item',
  66. 'tree_box_leaf',
  67. activeIndex == node.id ? 'tree_box_item_active' : '',
  68. ]"
  69. :style="{ paddingLeft: node.nodexIndex * 22 + 12 + 'px' }"
  70. @click="handleNodeClick(node, path)"
  71. :title="node.name"
  72. v-else
  73. >
  74. <template>
  75. <i class="el-icon-document"></i>
  76. </template>
  77. {{ node.name }}
  78. </span>
  79. </div>
  80. </Tree> -->
  81. </div>
  82. </template>
  83. <script>
  84. import "he-tree-vue/dist/he-tree-vue.css";
  85. import { getContent } from "@/api/ajax";
  86. import Cookies from "js-cookie";
  87. import { Tree, Fold, Draggable } from "he-tree-vue";
  88. import * as hp from "helper-js";
  89. export default {
  90. components: {
  91. Tree: Tree.mixPlugins([Fold, Draggable]),
  92. },
  93. props: [
  94. "changeId",
  95. "emptyQustion",
  96. "bookId",
  97. "tryFree",
  98. "changeTreeData",
  99. "currentTreeID",
  100. ],
  101. data() {
  102. return {
  103. treeData: [],
  104. draggable: false,
  105. foldAllAfterMounted: true,
  106. dialogFlag: false,
  107. formDialog: {
  108. name: "",
  109. radio: "1",
  110. is_courseware: "false",
  111. children: [],
  112. },
  113. curNode: null,
  114. curIndex: "",
  115. ondragend: {},
  116. oldLists: [], // 移动之前的数组
  117. oldPid: "", // 移动节点的父id
  118. oldId: "", // 移动节点的id
  119. destId: "", // 目标节点id
  120. destPosition: 0, // 目标位置0移动节点在前1后
  121. is_coursewareFlag: "false", // 移动的是否是课件节点
  122. activeIndex: "", // 高亮节点
  123. nodeLevel: "", // 高亮节点的level
  124. nodeName: "",
  125. pidList: [],
  126. loading: false,
  127. defaultProps: {
  128. children: "children",
  129. label: "label",
  130. isLeaf: (data, node) => {
  131. if (data.is_leaf === "true") {
  132. // 实体门店 叶子结点 不展示icon
  133. return true;
  134. }
  135. },
  136. },
  137. };
  138. },
  139. watch: {
  140. // 监听预览页面翻页的变化 树组件做出相同的操作
  141. async currentTreeID(newval, oldval) {
  142. if (newval) {
  143. this.activeIndex = newval;
  144. this.pidList = [];
  145. await this.unfoldData(this.activeIndex, this.treeData);
  146. await this.unfoldFather(this.treeData);
  147. }
  148. },
  149. },
  150. methods: {
  151. // 递归找到当前节点的所有父节点
  152. unfoldData(activeIndex, data, index, child) {
  153. for (let i = 0; i < data.length; i++) {
  154. if (data[i].id == activeIndex) {
  155. this.pidList.push(data[i].pid);
  156. if (Object.prototype.toString.call(index).indexOf("Number") != -1) {
  157. this.pidList.push(child.pid);
  158. }
  159. // return false
  160. } else if (data[i].children) {
  161. this.unfoldData(activeIndex, data[i].children, i, data[i]);
  162. }
  163. }
  164. },
  165. // 展示父节点
  166. unfoldFather(data) {
  167. for (let i = 0; i < data.length; i++) {
  168. if (this.pidList.indexOf(data[i].id) > -1) {
  169. data[i].$folded = false;
  170. if (data[i].children) {
  171. this.unfoldFather(data[i].children);
  172. }
  173. // return false
  174. } else if (data[i].children) {
  175. this.unfoldFather(data[i].children);
  176. }
  177. }
  178. },
  179. foldAll() {
  180. if (this.$refs.tree !== undefined) {
  181. this.$refs.tree.foldAll();
  182. }
  183. },
  184. getList() {
  185. let _this = this;
  186. this.loading = true;
  187. let MethodName = "book-book_manager-GetBookChapterStruct";
  188. let data = {
  189. book_id: this.bookId,
  190. };
  191. getContent(MethodName, data).then((res) => {
  192. this.loading = false;
  193. _this.handleData(res, 0);
  194. _this.treeData = res.nodes;
  195. _this.changeTreeData(this.treeData);
  196. _this.$nextTick(() => {
  197. _this.foldAll();
  198. });
  199. });
  200. },
  201. // 递归
  202. handleData(data, nodeIndex) {
  203. if (data.nodes) {
  204. data.nodes.forEach((item) => {
  205. item.label = item.name;
  206. item.pid = data.id;
  207. item.nodexIndex = nodeIndex;
  208. item.isLeaf = item.is_leaf === "true";
  209. if (item.nodes) {
  210. item.children = item.nodes;
  211. item.lists = item.nodes;
  212. this.handleData(item, nodeIndex + 1);
  213. }
  214. });
  215. }
  216. },
  217. handleNodeClick(data) {
  218. if (data.isLeaf) {
  219. this.activeIndex = data.id;
  220. this.nodeLevel = data.level_index;
  221. this.nodeName = data.name;
  222. this.changeId(data.id, data.name, data.is_free_trial);
  223. }
  224. },
  225. // 返给父级当前高亮节点的index以及level
  226. handleParentIndex() {
  227. return this.activeIndex + "###" + this.nodeLevel + "###" + this.nodeName;
  228. },
  229. },
  230. created() {
  231. this.getList();
  232. console.log(this.bookId);
  233. //this.$refs.tree.foldAllAfterMounted = true;
  234. },
  235. };
  236. </script>
  237. <style lang="scss" scoped>
  238. .tree_box {
  239. display: flex;
  240. justify-content: flex-start;
  241. align-items: center;
  242. height: 40px;
  243. cursor: pointer;
  244. .kuazhan {
  245. font-size: 40px;
  246. padding: 0 10px;
  247. cursor: pointer;
  248. }
  249. .tree_box_item {
  250. // display: flex;
  251. width: 100%;
  252. padding-left: 4px;
  253. color: #2c2c2c;
  254. height: 100%;
  255. align-items: center;
  256. line-height: 44px;
  257. padding-right: 60px;
  258. overflow: hidden;
  259. white-space: nowrap;
  260. text-overflow: ellipsis;
  261. font-weight: bold;
  262. }
  263. .tree_box_item:hover {
  264. color: #ff9900;
  265. > i {
  266. color: #ff9900;
  267. }
  268. }
  269. .tree_box_item_active,
  270. .tree_box_leaf:hover {
  271. color: #ff9900;
  272. > i {
  273. color: #ff9900;
  274. }
  275. }
  276. .tree_box_item_light {
  277. color: #ff9900;
  278. > i {
  279. color: #ff9900;
  280. }
  281. }
  282. .tree_box_item_active {
  283. color: #fff !important;
  284. background: #ff9900 !important;
  285. > i {
  286. color: #fff !important;
  287. }
  288. }
  289. }
  290. </style>
  291. <style lang="scss">
  292. .el-tree-node__expand-icon.is-leaf {
  293. opacity: 0;
  294. }
  295. .he_tree_view .he-tree .tree-node {
  296. border: 0;
  297. padding: 0;
  298. margin: 0;
  299. }
  300. .he_tree_content {
  301. [class*=" el-icon-"],
  302. [class^="el-icon-"] {
  303. color: rgba(0, 0, 0, 0.27);
  304. font-size: 16px;
  305. }
  306. .el-icon-plus {
  307. font-weight: bold;
  308. }
  309. .el-dialog__body {
  310. padding-right: 20px !important;
  311. }
  312. .el-icon_box {
  313. width: 24px;
  314. text-align: center;
  315. font-size: 0;
  316. > img {
  317. width: 100%;
  318. margin-top: 4px;
  319. }
  320. }
  321. }
  322. .he_tree_view {
  323. .tree-node-back {
  324. padding: 0 !important;
  325. }
  326. .tree_box_leaf {
  327. // padding-left: 80px !important;
  328. display: block;
  329. // width: 340px !important;
  330. font-weight: normal !important;
  331. }
  332. }
  333. </style>