treeList.vue 6.7 KB

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