leftFolder.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. <!-- 左侧文件夹结构 -->
  2. <template>
  3. <div class="left-folder">
  4. <el-scrollbar style="height: 100%">
  5. <el-row style="padding: 6px 12px; margin-top: 10px">
  6. <span style="font-size: 12px; color: #646c73">文件夹</span>
  7. <i class="el-icon-plus add-folder-icon" title="添加文件夹" @click="handleShowAddFolder"></i>
  8. </el-row>
  9. <ul class="folder-list">
  10. <li class="folder-item" style="cursor: auto" v-show="showAddFolder">
  11. <el-input
  12. style="width: 157px"
  13. ref="folderName"
  14. size="small"
  15. clearable
  16. v-model="folderName"
  17. @keyup.native.enter="handleClickAddFolder"
  18. placeholder="请输入文件夹名称"
  19. ></el-input>
  20. <i class="el-icon-refresh-left revoke-icon" title="撤销" @click="handleRevokeAddFolder"></i>
  21. <i class="el-icon-check confirm-icon" title="确认" @click="handleClickAddFolder"></i>
  22. </li>
  23. <li
  24. class="folder-item"
  25. :class="{ 'folder-select': folder.checked }"
  26. v-for="folder in folderData"
  27. :key="folder.id"
  28. :title="folder.name"
  29. @contextmenu.prevent="openMenu($event, folder)"
  30. @click="handleCheckFolder(folder)"
  31. >
  32. <span v-show="!folder.showInput" class="folder-item-text">{{ folder.name }}</span>
  33. <!-- <el-badge is-dot class="folder-item-number">103</el-badge> -->
  34. <el-input
  35. v-show="folder.showInput"
  36. style="width: 157px"
  37. :ref="`folderName${folder.id}`"
  38. size="small"
  39. clearable
  40. v-model="folder.updateName"
  41. @keyup.native.enter="handleUpdateFolderName(folder)"
  42. placeholder="请输入文件夹名称"
  43. ></el-input>
  44. <i v-show="folder.showInput" class="el-icon-refresh-left revoke-icon" title="撤销" @click="handleRevokeUpdateFolder(folder)"></i>
  45. <i v-show="folder.showInput" class="el-icon-check confirm-icon" title="确认" @click="handleUpdateFolderName(folder)"></i>
  46. </li>
  47. <!-- 右键菜单部分 -->
  48. <ul v-show="visible" :style="{ left: left + 'px', top: top + 'px' }" class="contextmenu">
  49. <li @click="showUpdateFolderName">重命名</li>
  50. <li @click="handleDeleteFolder">删除文件夹</li>
  51. </ul>
  52. </ul>
  53. </el-scrollbar>
  54. </div>
  55. </template>
  56. <script>
  57. export default {
  58. data() {
  59. return {
  60. showAddFolder: false,
  61. folderName: "未命名文件夹",
  62. folderData: [
  63. {
  64. id: 1,
  65. name: "能源系统",
  66. updateName: "能源系统",
  67. checked: false,
  68. showInput: false,
  69. },
  70. {
  71. id: 2,
  72. name: "排水系统",
  73. updateName: "排水系统",
  74. checked: false,
  75. showInput: false,
  76. },
  77. {
  78. id: 3,
  79. name: "消防水系统",
  80. updateName: "消防水系统",
  81. checked: false,
  82. showInput: false,
  83. },
  84. {
  85. id: 4,
  86. name: "公共照明系统公共照明系统公共照明系统公共照明系统",
  87. updateName: "公共照明系统公共照明系统公共照明系统公共照明系统",
  88. checked: false,
  89. showInput: false,
  90. },
  91. {
  92. id: 5,
  93. name: "暖通空调系统",
  94. updateName: "暖通空调系统",
  95. checked: false,
  96. showInput: false,
  97. },
  98. ],
  99. visible: false,
  100. top: 0,
  101. left: 0,
  102. rightClickFolder: null,
  103. };
  104. },
  105. mounted() {},
  106. methods: {
  107. // 点击添加文件夹icon打开弹窗
  108. handleShowAddFolder() {
  109. this.showAddFolder = true;
  110. this.$nextTick(() => {
  111. this.$refs.folderName.focus();
  112. });
  113. },
  114. // 创建文件夹
  115. handleClickAddFolder() {
  116. if (!this.folderName) {
  117. this.$message({ showClose: true, message: "请输入文件夹名称!" });
  118. } else if (
  119. this.folderData.find((folder) => {
  120. return folder.name === this.folderName;
  121. })
  122. ) {
  123. this.$message({ showClose: true, message: "您输入的文件夹已存在!" });
  124. } else {
  125. setTimeout(() => {
  126. this.folderData.unshift({
  127. id: Math.floor(Math.random() * 1000),
  128. name: this.folderName,
  129. updateName: this.folderName,
  130. checked: false,
  131. showInput: false,
  132. });
  133. this.$message.success("添加文件夹成功!");
  134. this.handleRevokeAddFolder();
  135. }, 1000);
  136. }
  137. },
  138. // 撤销添加文件夹
  139. handleRevokeAddFolder() {
  140. // 初始化添加文件夹状态
  141. this.showAddFolder = false;
  142. this.folderName = "未命名文件夹";
  143. },
  144. // 点击文件夹
  145. handleCheckFolder(folder) {
  146. this.$emit("changeFolder", folder);
  147. this.folderData.forEach((item) => {
  148. if (item.id === folder.id) {
  149. item.checked = true;
  150. } else {
  151. item.checked = false;
  152. }
  153. });
  154. },
  155. // 右键文件夹
  156. openMenu(e, folder) {
  157. this.visible = true;
  158. this.top = e.pageY;
  159. this.left = e.pageX;
  160. this.rightClickFolder = folder;
  161. },
  162. // 关闭右键菜单
  163. closeMenu() {
  164. this.visible = false;
  165. },
  166. // 显示要修改的文件夹输入框
  167. showUpdateFolderName() {
  168. if (this.rightClickFolder) {
  169. this.rightClickFolder.showInput = true;
  170. this.$nextTick(() => {
  171. this.$refs[`folderName${this.rightClickFolder.id}`][0].focus();
  172. });
  173. }
  174. },
  175. // 文件夹重命名
  176. handleUpdateFolderName(folder) {
  177. if (!folder.updateName) {
  178. this.$message({ showClose: true, message: "请输入文件夹名称!" });
  179. } else if (
  180. this.folderData.find((item) => {
  181. return item.name === folder.updateName;
  182. })
  183. ) {
  184. this.$message({ showClose: true, message: "您输入的文件夹已存在!" });
  185. } else {
  186. setTimeout(() => {
  187. folder.name = folder.updateName;
  188. this.$message.success("文件夹重命名成功!");
  189. folder.showInput = false;
  190. }, 1000);
  191. }
  192. },
  193. // 撤销重命名
  194. handleRevokeUpdateFolder(folder) {
  195. folder.updateName = folder.name;
  196. folder.showInput = false;
  197. },
  198. // 删除文件夹
  199. handleDeleteFolder() {
  200. if (this.rightClickFolder) {
  201. this.$confirm("此操作将永久删除该文件夹, 是否继续?", "提示", {
  202. confirmButtonText: "确定",
  203. cancelButtonText: "取消",
  204. type: "warning",
  205. }).then(() => {
  206. setTimeout(() => {
  207. this.folderData.splice(
  208. this.folderData.findIndex((item) => {
  209. return item.id === this.rightClickFolder.id;
  210. }),
  211. 1
  212. );
  213. this.$message({ type: "success", message: "删除成功!" });
  214. }, 1000);
  215. });
  216. }
  217. },
  218. },
  219. watch: {
  220. // 监听 visible,来触发关闭右键菜单,调用关闭菜单的方法
  221. visible(value) {
  222. if (value) {
  223. document.body.addEventListener("click", this.closeMenu);
  224. } else {
  225. document.body.removeEventListener("click", this.closeMenu);
  226. }
  227. },
  228. },
  229. };
  230. </script>
  231. <style lang="less" scoped>
  232. .left-folder {
  233. background: #f7f9fa;
  234. color: #1f2429;
  235. width: 100%;
  236. padding: 0 8px;
  237. height: 100%;
  238. padding-left: 6px;
  239. .add-folder-icon {
  240. float: right;
  241. margin-top: 3px;
  242. cursor: pointer;
  243. }
  244. .add-folder-icon:hover {
  245. color: #0091ff;
  246. }
  247. .folder-list {
  248. width: 100%;
  249. .folder-item {
  250. width: 100%;
  251. cursor: pointer;
  252. height: 40px;
  253. line-height: 40px;
  254. padding: 0 12px;
  255. .folder-item-text {
  256. display: inline-block;
  257. width: calc(100% - 35px);
  258. overflow: hidden;
  259. white-space: nowrap;
  260. text-overflow: ellipsis;
  261. }
  262. .folder-item-number {
  263. height: 18px;
  264. line-height: 18px;
  265. font-size: 12px;
  266. color: #646c73;
  267. margin-top: 11px;
  268. float: right;
  269. }
  270. .revoke-icon {
  271. cursor: pointer;
  272. margin-left: 8px;
  273. }
  274. .confirm-icon {
  275. cursor: pointer;
  276. color: #67c23a;
  277. margin-left: 8px;
  278. }
  279. }
  280. .folder-select {
  281. color: #0091ff;
  282. background-color: #e1f2ff;
  283. border-radius: 4px;
  284. }
  285. .folder-item:hover {
  286. color: #0091ff;
  287. background-color: #e1f2ff;
  288. border-radius: 4px;
  289. }
  290. .contextmenu {
  291. width: 120px;
  292. background: #fff;
  293. z-index: 3000;
  294. position: fixed;
  295. list-style-type: none;
  296. padding: 8px 0;
  297. border-radius: 4px;
  298. font-size: 12px;
  299. box-shadow: 0px 2px 10px 0px rgba(31, 35, 41, 0.1);
  300. li {
  301. margin: 0;
  302. padding: 8px 12px;
  303. cursor: pointer;
  304. }
  305. li:hover {
  306. color: #0091ff;
  307. background: #e1f2ff;
  308. }
  309. }
  310. }
  311. }
  312. </style>