QuestionFolderDialog.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <template>
  2. <el-dialog
  3. custom-class="side-dialog"
  4. :visible.sync="modalIsShow"
  5. :title="title"
  6. width="600px"
  7. :modal="false"
  8. :close-on-click-modal="false"
  9. :close-on-press-escape="false"
  10. append-to-body
  11. @open="visibleChange"
  12. >
  13. <el-tree
  14. class="folder-tree"
  15. :data="folderTree"
  16. node-key="id"
  17. default-expand-all
  18. :expand-on-click-node="false"
  19. :props="defaultProps"
  20. @node-click="nodeClick"
  21. >
  22. <span slot-scope="{ node, data }">
  23. <i class="icon icon-files-act node-icon"></i>
  24. <span v-if="data.id === 'none'" class="node-form">
  25. <el-form
  26. ref="modalFormComp"
  27. :model="modalForm"
  28. :rules="rules"
  29. size="mini"
  30. :show-message="false"
  31. inline
  32. >
  33. <el-form-item prop="name">
  34. <el-input
  35. v-model="modalForm.name"
  36. placeholder="请输入文件夹名称"
  37. clearable
  38. ></el-input>
  39. </el-form-item>
  40. <el-form-item>
  41. <el-button
  42. type="primary"
  43. icon="el-icon-check"
  44. @click="toCreateFolder"
  45. ></el-button>
  46. <el-button
  47. type="danger"
  48. icon="el-icon-close"
  49. @click="toRemoveFolder(node, data)"
  50. ></el-button>
  51. </el-form-item>
  52. </el-form>
  53. </span>
  54. <span
  55. v-else
  56. :class="['node-cont', { 'is-active': curNodeData.id === data.id }]"
  57. >{{ node.label }}</span
  58. >
  59. </span>
  60. </el-tree>
  61. <div slot="footer" class="box-justify">
  62. <el-button v-if="isEdit" type="primary" @click="toAddFolder"
  63. >新建文件夹</el-button
  64. >
  65. <div>
  66. <el-button v-if="!isEdit" type="primary" @click="confirm"
  67. >确定</el-button
  68. >
  69. <el-button @click="cancel">取消</el-button>
  70. </div>
  71. </div>
  72. </el-dialog>
  73. </template>
  74. <script>
  75. export default {
  76. name: "QuestionFolderDialog",
  77. props: {
  78. folderId: {
  79. type: [String, Number],
  80. default: "",
  81. },
  82. isEdit: {
  83. type: Boolean,
  84. default: true,
  85. },
  86. },
  87. data() {
  88. return {
  89. modalIsShow: false,
  90. folderTree: [
  91. {
  92. id: "1",
  93. parent: null,
  94. name: "根目录",
  95. children: [
  96. {
  97. id: "101",
  98. parent: "1",
  99. name: "2021-2022第一学期期末考试用",
  100. },
  101. {
  102. id: "102",
  103. parent: "1",
  104. name: "2021-2022第二学期期末考试用",
  105. },
  106. ],
  107. },
  108. ],
  109. defaultProps: {
  110. label: "name",
  111. },
  112. curNodeData: {},
  113. modalForm: {
  114. name: "",
  115. },
  116. rules: {
  117. name: [
  118. {
  119. required: true,
  120. message: "请输入文件夹名称",
  121. trigger: "change",
  122. },
  123. ],
  124. },
  125. };
  126. },
  127. computed: {
  128. title() {
  129. return this.isEdit ? "新建文件夹" : "选择文件夹";
  130. },
  131. },
  132. methods: {
  133. visibleChange() {
  134. if (this.folderId && !this.isEdit) {
  135. this.curNodeData = this.findNodeById(this.folderId);
  136. }
  137. },
  138. cancel() {
  139. this.modalIsShow = false;
  140. },
  141. open() {
  142. this.modalIsShow = true;
  143. },
  144. nodeClick(data) {
  145. if (data.id === "none" || data.id === this.curNodeData.id) return;
  146. this.clearPreNewNode();
  147. this.$nextTick(() => {
  148. this.curNodeData = this.findNodeById(data.id);
  149. });
  150. },
  151. findNodeById(id) {
  152. let curNode = null;
  153. const findNode = (data) => {
  154. if (curNode) return;
  155. data.forEach((item) => {
  156. if (curNode) return;
  157. if (item.id === id) {
  158. curNode = item;
  159. return;
  160. }
  161. if (item.children && item.children.length) findNode(item.children);
  162. });
  163. };
  164. findNode(this.folderTree);
  165. return curNode || {};
  166. },
  167. clearPreNewNode() {
  168. const removePreNewChild = (data) => {
  169. data = data.filter((item) => item.id !== "none");
  170. return data.map((item) => {
  171. if (item.children && item.children.length)
  172. item.children = removePreNewChild(item.children);
  173. return item;
  174. });
  175. };
  176. this.folderTree = removePreNewChild(this.folderTree);
  177. },
  178. toAddFolder() {
  179. if (!this.curNodeData.id) {
  180. this.$message.error("请先选择文件夹!");
  181. return;
  182. }
  183. const newChild = { id: "none", name: "", parentId: this.curNodeData.id };
  184. if (!this.curNodeData.children) {
  185. this.$set(this.curNodeData, "children", []);
  186. }
  187. this.curNodeData.children.push(newChild);
  188. this.modalForm = { name: "" };
  189. },
  190. async toCreateFolder() {
  191. const valid = await this.$refs.modalFormComp.validate().catch(() => {});
  192. if (!valid) return;
  193. },
  194. toRemoveFolder(node, data) {
  195. const parent = node.parent;
  196. const children = parent.data.children || parent.data;
  197. const index = children.findIndex((d) => d.id === data.id);
  198. children.splice(index, 1);
  199. },
  200. confirm() {
  201. if (!this.curNodeData.id) {
  202. this.$message.error("请选择文件夹!");
  203. return;
  204. }
  205. this.$emit("selected", this.curNodeData);
  206. },
  207. },
  208. };
  209. </script>