Vue3+ts 使用node基于fs模块在视图上对系统文件、目录进行读写、进入下一级返回上一级的操作。

简介

公司新需求,对电脑硬盘的文件进行访问操作,并显示到视图上,要想访问电脑硬盘文件,浏览器是没有权限可以进行访问的,必须是桌面应用,也就是需要使用到electron。如果只是访问项目内的文件内容,就不用使用electron。
 

完整代码在结尾处,可直接复制使用。

一、安装node

确保提前安装了fs模块,你可以使用以下命令进行安装:

npm install --save fs

二、引入fs方法进行访问文件目录并显示到视图

通过fs的readdirSync根据路径获取到文件夹目录数据,循环获取到的数据再通过fs的statSync对目录内容进行分类。

注意:如果访问不了,要确定打开了文件权限,允许读写其内容才行。

<script setup lang="ts">
import { ref } from "vue";
import cataLogue from "../assets/image/cata-logue.png";//文件夹图片
import text from "../assets/image/text.png";//文件图片
import back from "../assets/image/back.png";//返回上一级图片
const fs = require("fs"); // 引入node的fs模块
const items: any = ref([]);
let directoryPath = "/Users/xxx/xxx/xxx"; // 替换为实际的目录路径
// 获取文件夹目录并进行分类
getCatalogue(directoryPath);
async function getCatalogue(path: any) {
  try {
    // 通过fs的readdirSync获取到指定路径的文件夹目录数据
    const filesList = fs.readdirSync(path);
    // 通过循环使用fs的statSync判断目录中那些为文件和文件夹
    const itemsList = filesList.map((fileName: any) => {
      const filePath = `${path}/${fileName}`;
      const stats = fs.statSync(filePath);
      return {
        name: fileName,
        isDirectory: stats.isDirectory(),
      };
    });
    // 将分类好的数据赋值items反显到视图上
    items.value = itemsList;
  } catch (err) {
    console.error(err);
  }
  return Promise.resolve();
}
</script>

当获取到了文件夹目录数据后通过循环数据内容反显到视图上

<template>
  <div style="width: 100%; height: 100%">
    <h1>文件夹目录</h1>
    <img v-if="isShow" style="width: 50px" :src="back" @click="backUpLevel" />
    <div class="box">
      <span
        class="logue-content"
        v-for="item in items"
        :key="item.name"
        @dblclick="openItem(item)"
      >
        <img :src="item.isDirectory ? text : cataLogue" />
        <div>{{ item.name }}</div>
      </span>
    </div>
  </div>
</template>

这样就可以在视图上看到内容了。 

 这个时候已经完成了展示,开始实现访问下一级已经返回。


三、访问下一级目录

template里面咱们循环数据时,有两个方法分别是进入下一级目录的openItem和返回上一级的backUpLevel。
通过拼接地址重新调用getCateLogue() 获取到下一级数据并反显

<script setup lang="ts">
import { ref } from "vue";
import cataLogue from "../assets/image/cata-logue.png";
import text from "../assets/image/text.png";
import back from "../assets/image/back.png";
const fs = require("fs"); // 引入node的fs模块
const items: any = ref([]);
const fileContent: any = ref("");
const isShow: any = ref(false);
const fileDataShow: any = ref(false);
let directoryPath = "/Users/sanyuanui/Desktop/electronLocal"; // 替换为实际的目录路径
// 获取文件夹目录并进行分类
getCatalogue(directoryPath);
async function getCatalogue(path: any) {
  try {
    // 通过fs的readdirSync获取到指定路径的文件夹目录数据
    const filesList = fs.readdirSync(path);
    // 通过循环使用fs的statSync判断目录中那些为文件和文件夹
    const itemsList = filesList.map((fileName: any) => {
      const filePath = `${path}/${fileName}`;
      const stats = fs.statSync(filePath);
      return {
        name: fileName,
        isDirectory: stats.isDirectory(),
      };
    });
    // 将分类好的数据赋值items反显到视图上
    items.value = itemsList;
  } catch (err) {
    console.error(err);
  }
  return Promise.resolve();
}
// 通过双击事件进入下一级目录
const openItem = (item: any) => {
  // 拼接下一级的地址并进行访问
  directoryPath = `${directoryPath}/${item.name}`;
  // 当双击的是文件夹时
  if (item.isDirectory) {
    isShow.value = true;
    getCatalogue(directoryPath);
  } else {
    // 点击的是文件时
    fileDataShow.value = true;
    getFileData(directoryPath);
  }
};
// 返回上一级
function backUpLevel() {
  directoryPath = directoryPath.split("/").slice(0, -1).join("/");
  getCatalogue(directoryPath);
  if (directoryPath === "/Users/sanyuanui/Desktop/electronLocal") {
    isShow.value = false;
  }
}
</script>

四、获取文件信息,反显到textarea上 即可进行对文件操作

<script setup lang="ts">
import { ref } from "vue";
import cataLogue from "../assets/image/cata-logue.png";
import text from "../assets/image/text.png";
import back from "../assets/image/back.png";
const fs = require("fs"); // 引入node的fs模块
const items: any = ref([]);
const fileContent: any = ref("");
const isShow: any = ref(false);
const fileDataShow: any = ref(false);
let directoryPath = "/Users/sanyuanui/Desktop/electronLocal"; // 替换为实际的目录路径
// 获取文件夹目录并进行分类
getCatalogue(directoryPath);
async function getCatalogue(path: any) {
  try {
    // 通过fs的readdirSync获取到指定路径的文件夹目录数据
    const filesList = fs.readdirSync(path);
    // 通过循环使用fs的statSync判断目录中那些为文件和文件夹
    const itemsList = filesList.map((fileName: any) => {
      const filePath = `${path}/${fileName}`;
      const stats = fs.statSync(filePath);
      return {
        name: fileName,
        isDirectory: stats.isDirectory(),
      };
    });
    // 将分类好的数据赋值items反显到视图上
    items.value = itemsList;
  } catch (err) {
    console.error(err);
  }
  return Promise.resolve();
}
// 通过双击事件进入下一级目录
const openItem = (item: any) => {
  // 拼接下一级的地址并进行访问
  directoryPath = `${directoryPath}/${item.name}`;
  // 当双击的是文件夹时
  if (item.isDirectory) {
    isShow.value = true;
    getCatalogue(directoryPath);
  } else {
    // 点击的是文件时
    fileDataShow.value = true;
    getFileData(directoryPath);
  }
};
// 返回上一级
function backUpLevel() {
  directoryPath = directoryPath.split("/").slice(0, -1).join("/");
  getCatalogue(directoryPath);
  if (directoryPath === "/Users/sanyuanui/Desktop/electronLocal") {
    isShow.value = false;
  }
}
// 获取文件信息
async function getFileData(path: string) {
  try {
    // 通过fs的readFileSync访问传输进来的地址文件数据
    const content = fs.readFileSync(path, { encoding: "utf-8" });
    // 讲文件数据反显到视图上
    fileContent.value = content;
  } catch (error) {
    console.error(error);
  }
}
// 保存文件内容
function saveFile() {
  try {
    fs.writeFileSync(directoryPath, fileContent.value, { encoding: "utf-8" });
    fileDataShow.value = false;
    directoryPath = directoryPath.split("/").slice(0, -1).join("/");
    console.log("文件保存成功!");
  } catch (error) {
    console.error(error);
  }
}
</script>

 五、完整代码内容 复制粘贴即可使用(图片需更换地址)

<template>
  <div style="width: 100%; height: 100%">
    <h1>文件夹目录</h1>
    <img v-if="isShow" style="width: 50px" :src="back" @click="backUpLevel" />
    <div class="box">
      <span
        class="logue-content"
        v-for="item in items"
        :key="item.name"
        @dblclick="openItem(item)"
      >
        <img :src="item.isDirectory ? text : cataLogue" />
        <div>{{ item.name }}</div>
      </span>
    </div>
    <!-- 文件夹内容 -->
    <div v-if="fileDataShow">
      <textarea v-model="fileContent" rows="10" cols="50"></textarea>
      <button style="background-color: #fff" @click="saveFile">保存</button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";
import cataLogue from "../assets/image/cata-logue.png";
import text from "../assets/image/text.png";
import back from "../assets/image/back.png";
const fs = require("fs"); // 引入node的fs模块
const items: any = ref([]);
const fileContent: any = ref("");
const isShow: any = ref(false);
const fileDataShow: any = ref(false);
let directoryPath = "/Users/sanyuanui/Desktop/electronLocal"; // 替换为实际的目录路径
// 获取文件夹目录并进行分类
getCatalogue(directoryPath);
async function getCatalogue(path: any) {
  try {
    // 通过fs的readdirSync获取到指定路径的文件夹目录数据
    const filesList = fs.readdirSync(path);
    // 通过循环使用fs的statSync判断目录中那些为文件和文件夹
    const itemsList = filesList.map((fileName: any) => {
      const filePath = `${path}/${fileName}`;
      const stats = fs.statSync(filePath);
      return {
        name: fileName,
        isDirectory: stats.isDirectory(),
      };
    });
    // 将分类好的数据赋值items反显到视图上
    items.value = itemsList;
  } catch (err) {
    console.error(err);
  }
  return Promise.resolve();
}
// 通过双击事件进入下一级目录
const openItem = (item: any) => {
  // 拼接下一级的地址并进行访问
  directoryPath = `${directoryPath}/${item.name}`;
  // 当双击的是文件夹时
  if (item.isDirectory) {
    isShow.value = true;
    getCatalogue(directoryPath);
  } else {
    // 点击的是文件时
    fileDataShow.value = true;
    getFileData(directoryPath);
  }
};
// 返回上一级
function backUpLevel() {
  directoryPath = directoryPath.split("/").slice(0, -1).join("/");
  getCatalogue(directoryPath);
  if (directoryPath === "/Users/sanyuanui/Desktop/electronLocal") {
    isShow.value = false;
  }
}
// 获取文件信息
async function getFileData(path: string) {
  try {
    // 通过fs的readFileSync访问传输进来的地址文件数据
    const content = fs.readFileSync(path, { encoding: "utf-8" });
    // 讲文件数据反显到视图上
    fileContent.value = content;
  } catch (error) {
    console.error(error);
  }
}
// 保存文件内容
function saveFile() {
  try {
    fs.writeFileSync(directoryPath, fileContent.value, { encoding: "utf-8" });
    fileDataShow.value = false;
    directoryPath = directoryPath.split("/").slice(0, -1).join("/");
    console.log("文件保存成功!");
  } catch (error) {
    console.error(error);
  }
}
</script>
<style lang="less" scoped>
.box {
  width: 100%;
  height: 100%;
}
.logue-content {
  display: inline-block;
  width: 150px;
  height: 120px;
  img {
    width: 50px;
    height: 50px;
  }
}
</style>

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值