feat: 支持读写本地文件

This commit is contained in:
Frankie Huang 2025-04-04 19:13:23 +08:00
parent 88a9c42aa2
commit c09c8b5e9c
4 changed files with 136 additions and 17 deletions

View File

@ -43,3 +43,9 @@ This template should help get you started developing with Tauri + Vue 3 in Vite.
1. `npm run tauri add fs`
2. `npm run tauri add dialog`
## 支持读本地目录,读写本地文件
1. 新建 SelectFolder.vue 用于打开本地目录
2. 在 App.vue 使用组件 SelectFolder 和 MarkdownEditor.vue
3. 使用 plugin-fs 插件读写本地文件内容

View File

@ -9,6 +9,22 @@
"core:default",
"opener:default",
"fs:default",
"dialog:default"
"dialog:default",
{
"identifier": "fs:scope",
"allow": [
{
"path": "$HOME/**"
}
]
},
{
"identifier": "fs:allow-app-write",
"allow": [
{
"path": "$HOME/**"
}
]
}
]
}

View File

@ -1,7 +1,12 @@
<script setup>
import { ref } from "vue";
import { invoke } from "@tauri-apps/api/core";
import { readTextFile, writeTextFile } from '@tauri-apps/plugin-fs';
import MarkdownEditor from './components/MarkdownEditor.vue'
import SelectFolder from './components/SelectFolder.vue'
const markdownRef = ref(null);
const filePath = ref("");
const greetMsg = ref("");
const name = ref("");
@ -9,30 +14,46 @@ async function greet() {
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
greetMsg.value = await invoke("greet", { name: name.value });
}
async function showFileTree(tree) {
console.log(tree)
}
async function readFileContent() {
try {
console.log('文件读取成功:', markdownRef.value.setMarkdownCode(await readTextFile(filePath.value)))
} catch (err) {
console.error('文件读取失败:', err);
}
}
async function writeFileContent() {
console.log('文件新的内容:', markdownRef.value.getMarkdownCode())
try {
console.log('文件更新成功:', await writeTextFile(filePath.value, markdownRef.value.getMarkdownCode()))
} catch (err) {
console.error('文件更新失败:', err);
}
}
</script>
<template>
<main class="container">
<h1>Welcome to Tauri + Vue</h1>
<div class="row">
<SelectFolder @folder-selected="showFileTree" />
</div>
<div class="row">
<a href="https://vitejs.dev" target="_blank">
<img src="/vite.svg" class="logo vite" alt="Vite logo" />
</a>
<a href="https://tauri.app" target="_blank">
<img src="/tauri.svg" class="logo tauri" alt="Tauri logo" />
</a>
<a href="https://vuejs.org/" target="_blank">
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
</a>
<input id="file-path-input" v-model="filePath" placeholder="Enter a file path..." />
<button @click="readFileContent">读取指定文件</button>
<button @click="writeFileContent">更新指定文件</button>
</div>
<p>Click on the Tauri, Vite, and Vue logos to learn more.</p>
<form class="row" @submit.prevent="greet">
<input id="greet-input" v-model="name" placeholder="Enter a name..." />
<button type="submit">Greet</button>
</form>
<p>{{ greetMsg }}</p>
<MarkdownEditor ref="markdownRef"
width='1000px'
height='1000px'
markdownCode="# hello tauri"
/>
</main>
</template>

View File

@ -0,0 +1,76 @@
<template>
<button @click="selectFolder">选择目录</button>
</template>
<script>
import { join } from '@tauri-apps/api/path';
import { open } from '@tauri-apps/plugin-dialog';
import { readDir } from '@tauri-apps/plugin-fs';
//
let folderTreeData = {
"path": "root-path/root",
"name": "root",
"nodes": [
{
"path": "root-path/root/folder1",
"name": "folder1",
"nodes": [
{
"path": "root-path/root/folder1/folder1-file2",
"name": "folder1-file2.txt.md",
"suffix": "md",
},
]
},
{
"path": "root-path/root/file3",
"name": "file3.txt",
"suffix": "txt",
},
]
}
async function readDirRecursively(parent, path) {
//
const folderPath = await join(parent, path);
let folderTreeNode = {
"path": folderPath,
"name": folderPath.split('/').pop(),
"nodes": []
}
//
const entries = await readDir(folderPath);
for (const entry of entries) {
const entryPath = await join(folderPath, entry.name);
if (entry.isDirectory) {
folderTreeNode.nodes.push(await readDirRecursively(folderPath, entry.name))
} else {
const fileSuffix = entry.name.split('.').pop()
folderTreeNode.nodes.push({
"path": entryPath,
"name": entry.name,
"suffix": fileSuffix,
})
}
}
return folderTreeNode
}
export default {
methods: {
async selectFolder() {
const filePath = await open(
{
filters: [{ name: 'All Files', extensions: ['.'] }],
directory: true
});
if (filePath) {
folderTreeData = await readDirRecursively(filePath, '')
this.$emit('folder-selected', folderTreeData);
}
}
}
}
</script>