treeList.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. <template>
  2. <div class="treeList">
  3. <div class="title commons-title">
  4. {{ title }}
  5. </div>
  6. <div class="search">
  7. <el-input
  8. v-model="search"
  9. placeholder="请输入搜索内容"
  10. clearable
  11. @clear="search = ''"
  12. @keyup.enter="searchChange"
  13. ></el-input>
  14. <!-- <el-button type="primary" @click="searchChange">搜索</el-button> -->
  15. <el-button type="primary" plain @click="add({ id: 0 })">
  16. <el-icon :size="20">
  17. <Plus />
  18. </el-icon>
  19. </el-button>
  20. </div>
  21. <div class="box">
  22. <el-tree
  23. :data="data"
  24. ref="tree"
  25. node-key="id"
  26. @node-click="treeChange"
  27. default-expand-all
  28. :filter-node-method="filterNode"
  29. >
  30. <template #default="{ node, data }">
  31. <div class="custom-tree-node">
  32. <div style="flex: 1">{{ node.label }}</div>
  33. <div style="float: right; width: 71px; margin-left: 10px">
  34. <el-icon :size="17" @click.stop="() => edit(node, data)">
  35. <Edit />
  36. </el-icon>
  37. <el-icon
  38. :size="17"
  39. style="margin-left: 10px"
  40. @click.stop="() => add(data)"
  41. >
  42. <Plus />
  43. </el-icon>
  44. <el-icon
  45. :size="17"
  46. style="margin-left: 10px"
  47. @click.stop="() => del(data)"
  48. >
  49. <Delete />
  50. </el-icon>
  51. </div>
  52. </div>
  53. </template>
  54. </el-tree>
  55. </div>
  56. <el-dialog
  57. :title="treeModalType == 'add' ? '添加分类' : '编辑分类'"
  58. v-model="treeModal"
  59. width="400"
  60. v-loading="loading"
  61. >
  62. <byForm
  63. :formConfig="formConfig"
  64. :formOption="formOption"
  65. v-model="formData.data"
  66. :rules="rules"
  67. ref="byform"
  68. >
  69. </byForm>
  70. <template #footer>
  71. <el-button @click="treeModal = false" size="large">取 消</el-button>
  72. <el-button
  73. type="primary"
  74. @click="submitForm('byform')"
  75. size="large"
  76. :loading="submitLoading"
  77. >
  78. 确 定
  79. </el-button>
  80. </template>
  81. </el-dialog>
  82. </div>
  83. </template>
  84. <script setup>
  85. import { toRaw } from "vue";
  86. import { ElMessage, ElMessageBox } from "element-plus";
  87. import byForm from "@/components/byForm/index";
  88. const props = defineProps({
  89. title: {
  90. type: String,
  91. default: "分类",
  92. },
  93. submitType: {
  94. type: String,
  95. default: "1", //默认产品
  96. },
  97. data: {
  98. type: Array,
  99. default: [],
  100. },
  101. });
  102. onMounted(() => {});
  103. const search = ref("");
  104. const emit = defineEmits(["update:modelValue"]);
  105. const { proxy } = getCurrentInstance();
  106. const treeChange = (e, data) => {
  107. if (proxy.type == "radio") {
  108. emit("update:modelValue", e.id);
  109. emit("change", e);
  110. } else {
  111. emit("change", e);
  112. }
  113. };
  114. // const filterNode = (value, data, node) => {
  115. // if (!value) return true;
  116. // return data.label.indexOf(value) !== -1;
  117. // };
  118. const getParents = (node, name, key) => {
  119. if (node.parent && node.parent.data[key]) {
  120. name += node.parent.data[key];
  121. return getParents(node.parent, name, key);
  122. }
  123. return name;
  124. };
  125. // 以下可实现搜索显示子节点
  126. const filterNode = (value, data, node) => {
  127. let names = getParents(node, node.data.label, "label");
  128. let isName = names.indexOf(value) !== -1;
  129. return !value || isName ? true : false;
  130. };
  131. const searchChange = () => {
  132. proxy.$refs.tree.filter(search.value);
  133. };
  134. const byform = ref(null);
  135. const treeListData = ref([]);
  136. let treeModal = ref(false);
  137. let submitLoading = ref(false);
  138. let treeModalType = ref("add");
  139. let currentNode = reactive({
  140. id: "",
  141. });
  142. let formData = reactive({
  143. data: {
  144. name: "",
  145. parentId: "",
  146. definition: props.submitType,
  147. },
  148. });
  149. const formOption = reactive({
  150. inline: true,
  151. labelWidth: 100,
  152. itemWidth: 100,
  153. rules: [],
  154. });
  155. let rules = ref({
  156. name: [{ required: true, message: "请输入分类名称", trigger: "blur" }],
  157. });
  158. const formConfig = computed(() => {
  159. return [
  160. {
  161. type: "input",
  162. prop: "name",
  163. label: "分类名称",
  164. required: true,
  165. },
  166. ];
  167. });
  168. const add = (data) => {
  169. treeModal.value = true;
  170. treeModalType.value = "add";
  171. formData.data = {
  172. name: "",
  173. parentId: "",
  174. definition: props.submitType,
  175. };
  176. formData.data.parentId = data.id;
  177. };
  178. const edit = (node, data) => {
  179. treeModal.value = true;
  180. treeModalType.value = "edit";
  181. formData.data = {
  182. name: data.label,
  183. id: data.id,
  184. definition: props.submitType,
  185. };
  186. };
  187. const del = (data) => {
  188. ElMessageBox.confirm("此操作将永久删除该数据, 是否继续?", "提示", {
  189. confirmButtonText: "确定",
  190. cancelButtonText: "取消",
  191. type: "warning",
  192. }).then(() => {
  193. // 删除
  194. proxy
  195. .post("/productClassify/delete", {
  196. id: data.id,
  197. })
  198. .then((res) => {
  199. ElMessage({
  200. message: "删除成功",
  201. type: "success",
  202. });
  203. getTreeList();
  204. });
  205. });
  206. };
  207. const submitForm = () => {
  208. byform.value.handleSubmit((valid) => {
  209. submitLoading.value = true;
  210. proxy.post("/productClassify/" + treeModalType.value, formData.data).then(
  211. (res) => {
  212. ElMessage({
  213. message: treeModalType.value == "add" ? "添加成功" : "编辑成功",
  214. type: "success",
  215. });
  216. getTreeList();
  217. treeModal.value = false;
  218. submitLoading.value = false;
  219. },
  220. (err) => {
  221. submitLoading.value = false;
  222. }
  223. );
  224. });
  225. };
  226. const getTreeList = () => {
  227. emit("changeTreeList");
  228. // proxy
  229. // .post("/productClassify/tree", {
  230. // parentId: "",
  231. // name: "",
  232. // definition: props.submitType,
  233. // })
  234. // .then((message) => {
  235. // treeListData.value = message;
  236. // });
  237. };
  238. // getTreeList();
  239. const handleMouseOver = (data) => {
  240. console.log(data, "sss");
  241. // currentNode.id = toRaw(data).id;
  242. };
  243. </script>
  244. <style lang="scss">
  245. .custom-tree-node {
  246. flex: 1;
  247. display: flex;
  248. align-items: center;
  249. justify-content: space-between;
  250. font-size: 14px;
  251. padding-right: 8px;
  252. }
  253. .treeList {
  254. display: block;
  255. height: 100%;
  256. background: #fff;
  257. padding: 20px;
  258. height: calc(100vh - 140px);
  259. .search {
  260. margin-bottom: 20px;
  261. .el-input {
  262. width: calc(100% - 70px);
  263. margin-right: 10px;
  264. text-align: center;
  265. }
  266. }
  267. // .searh,.title,.box{
  268. // padding-left:20px ;
  269. // }
  270. .box {
  271. padding-right: 0px;
  272. height: calc(100vh - 270px);
  273. overflow-y: auto;
  274. overflow-x: auto;
  275. .el-tree {
  276. // .el-tree-node__content {
  277. // display: block;
  278. // }
  279. .el-tree-node > .el-tree-node__children {
  280. overflow: visible;
  281. }
  282. }
  283. }
  284. }
  285. </style>