33 <div class =" head" >
44 <div class =" title" >目录</div >
55
6- <el-icon class =" icon" @click =" openDir()" ><Files /></el-icon >
6+ <el-tooltip content =" 切换目录" placement =" bottom" >
7+ <el-icon class =" icon" @click =" openDir()" ><Files /></el-icon >
8+ </el-tooltip >
79 </div >
810
911 <div class =" content" >
2123 <div class =" node-item" >
2224 <div class =" icon" >
2325 <el-icon v-if =" data.dir" size =" 18" >
24- <Refresh v-if =" node.expanded" @click.stop = " refreshNode(node) " />
26+ <FolderOpened v-if =" node.expanded" />
2527 <Folder v-else />
2628 </el-icon >
2729
3133 <div class =" text" >
3234 <div class =" t" >{{ node.label }}</div >
3335 </div >
36+
37+ <div class =" edit" v-show =" data.dir && node.expanded" >
38+ <el-tooltip content =" 刷新目录" placement =" top" >
39+ <el-icon @click.stop =" refreshNode(node)" ><Refresh /></el-icon >
40+ </el-tooltip >
41+
42+ <el-tooltip content =" 创建文件" placement =" top" >
43+ <el-icon @click.stop =" addFile(node)" ><DocumentAdd /></el-icon >
44+ </el-tooltip >
45+ </div >
3446 </div >
3547 </template >
3648 </el-tree >
4254<script lang="ts" setup>
4355import { ref } from ' vue'
4456import axios from ' axios'
45- import { Files , Folder , Refresh } from ' @element-plus/icons-vue'
57+ import { ElMessageBox } from ' element-plus'
58+ import { Files , Folder , FolderOpened , Refresh , DocumentAdd } from ' @element-plus/icons-vue'
4659
4760import FileView from ' @/components/FileView.vue'
4861
@@ -52,7 +65,12 @@ import { useEditorStore } from '@/store/editor'
5265import { useLikeStore } from ' @/store/like'
5366import { useOpenStore } from ' @/store/open'
5467
55- import type { TreeInstance , TreeData , TreeNodeData , RenderContentContext } from ' element-plus'
68+ import {
69+ type TreeInstance ,
70+ type TreeData ,
71+ type TreeNodeData ,
72+ type RenderContentContext ,
73+ } from ' element-plus'
5674
5775const editor = useEditorStore ()
5876const like = useLikeStore ()
@@ -64,6 +82,31 @@ const openDir = async () => {
6482 open .show = ' dir'
6583}
6684
85+ const addFile = async (node : RenderContentContext [' node' ]) => {
86+ try {
87+ const { value } = await ElMessageBox .prompt (` ${node .data .value }/ ` , ' 创建文件' , {
88+ inputValidator : (v ) => (v ? true : ' 请输入文件名' ),
89+ inputPlaceholder: ' 文件名+后缀' ,
90+ confirmButtonText: ' 确认' ,
91+ cancelButtonText: ' 取消' ,
92+ })
93+
94+ const path = ` ${node .data .value }/${value } `
95+
96+ await axios .post (
97+ HOST ,
98+ { encode: ' utf8' , path , value: ' ' , force: 1 },
99+ { params: { _api: ' save' } },
100+ )
101+
102+ editor .add (path , { keep: false })
103+
104+ refreshNode (node )
105+ } catch {
106+ return
107+ }
108+ }
109+
67110const refreshNode = (node : RenderContentContext [' node' ]) => {
68111 loadNode (node , (data ) => node .key && treeRef .value ?.updateKeyChildren (node .key , data ))
69112}
@@ -112,6 +155,13 @@ const openNode = (data: TreeNodeData) => {
112155 display : flex ;
113156 align-items : center ;
114157 gap : 4px ;
158+ padding-right : 4px ;
159+
160+ & :hover {
161+ > .edit {
162+ display : flex ;
163+ }
164+ }
115165
116166 > .icon {
117167 width : 24px ;
@@ -136,5 +186,11 @@ const openNode = (data: TreeNodeData) => {
136186 text-overflow : ellipsis ;
137187 }
138188 }
189+
190+ > .edit {
191+ display : none ;
192+ align-items : center ;
193+ gap : 8px ;
194+ }
139195}
140196 </style >
0 commit comments