【问题标题】:Vue.js - Write JSON object to local fileVue.js - 将 JSON 对象写入本地文件
【发布时间】:2018-07-14 15:58:50
【问题描述】:

不久前我开始学习 Vue.js,不久之后,我开始了一个更大的项目,但我没有记住 Javascript 与本地文件系统交互的选项有限。 我是通过vue-cli设置项目的,所以我必须通过npm start启动网站。

所述项目包含一个 JSON 文件的可视化编辑器。当我想实现保存按钮时,我意识到将 JSON 文件写入/保存(将来可能会读取)到我的本地机器是一项相当困难的任务。

我已经尝试过使用 node 的 fs 库,认为它会起作用,因为它是使用 node 启动的。 我还尝试了几个外部库,例如write-json-file npm 库。

我已经到了没有想法的地步,并且会做几乎任何必要的事情来让它发挥作用。

【问题讨论】:

  • 要与文件系统交互,您很可能需要一些节点服务器。就像使用 express 或某种网络服务器一样,您可以从您的 vue.js webapp 进行通信
  • 你是使用服务器端还是客户端生成json并写入本地?
  • json 数据将被“实时”创建并存储在 vuex 存储中。永远不会有一个“真正的”服务器端,因为它应该像一个 Windows 应用程序,永远不会通过互联网访问。我知道在这样的事情上使用 javascript 很奇怪,但它的规范是一个基于 Web 的项目。
  • 我认为如果使用浏览器环境,您只能创建一个 blob 来下载或写入本地存储或 IndexDB。如果有帮助,我可以分享一个我做过的例子。但是作为您的描述,您想要实现诸如 VSCode 或 Atom 之类的东西。对于您的用例,您可以尝试查看 Electron
  • 下载按钮似乎是一个可行的选择,如果它不是那么复杂的话:) 我知道还有其他选择,但它更像是我大学范围内的一个教育项目,而不是现实生活中的用例。举个例子就好了

标签: javascript json node.js vue.js vuejs2


【解决方案1】:

这就是我在 Vue 项目中编辑 JSON 文件的方式。在这种情况下,如果您运行该文件,它将创建一个新的 data.json 文件并将 Price 添加到每个 JSON 对象:

const fs = require("fs");

let cars = [
  {
    Name: "chevrolet chevelle malibu",
    Miles_per_Gallon: 18,
    Cylinders: 8,
    Displacement: 307,
    Horsepower: 130,
    Weight_in_lbs: 3504,
    Acceleration: 12,
    Year: "1970-01-01",
    Origin: "USA"
  },
  {
    Name: "buick skylark 320",
    Miles_per_Gallon: 15,
    Cylinders: 8,
    Displacement: 350,
    Horsepower: 165,
    Weight_in_lbs: 3693,
    Acceleration: 11.5,
    Year: "1970-01-01",
    Origin: "USA"
  }
];
cars.forEach(car => {
  car.price = 12000;
});

let data = JSON.stringify(cars);
fs.writeFileSync("data.json", data);

【讨论】:

  • 我收到错误fs.writeFileSync is not a function
【解决方案2】:

有 3 种方法可以做到这一点。

  1. 写入本地存储

  2. 创建一个 Blob 并调用一个事件来下载它

  3. 将其包装到一个电子应用程序中并使用节点fs模块保存文件

我可以在这里为您展示这 3 个案例的示例

index.html

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Vue test</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue.js"></script>
</head>
<body>
<div id="vue-app">
    <form>
        <input type="text" v-model="name"/>{{name}}<br/>
        <input type="text" v-model="last"/>{{last}}<br/>
        <input type="text" v-model="index"/>{{index}}<br/>
        <select v-model="grade">
            <option>5</option>
            <option>6</option>
            <option>7</option>
            <option>8</option>
            <option>9</option>
            <option>10</option>
        </select>
        {{grade}}
        <button type="button" v-on:click="add()">Add To Table</button>
        <button type="button" v-on:click="saveFile()">saveFile</button>
    </form>
    <table border="1">
        <thead><td>Name</td><td>Last Name</td><td>Index</td><td>Grade</td></thead>
        <tbody>
        <tr v-for="x in arr">
            <td>{{x.first}}</td>
            <td>{{x.lastn}}</td>
            <td>{{x.index}}</td>
            <td>{{x.grade}}</td>
        </tr>
        </tbody>
    </table>
</div>
<script src="test.js"></script>
</body>
</html>

test.js(写入本地存储

new Vue ({
  el: '#vue-app',
  data: {
      name: '',
      last: '',
      index: 0,
      grade: 0,
      arr: []
  },

  methods: {
      add: function (e) {
          this.arr.push({first: this.name, lastn: this.last, index: this.index, grade: this.grade});
          console.log(1);
      },
      saveFile: function() {
        const data = JSON.stringify(this.arr)
        window.localStorage.setItem('arr', data);
        console.log(JSON.parse(window.localStorage.getItem('arr')))
  }
});

创建一个 Blob 并调用一个事件来下载它

仅更改 saveFile 函数

saveFile: function() {
    const data = JSON.stringify(this.arr)
    const blob = new Blob([data], {type: 'text/plain'})
    const e = document.createEvent('MouseEvents'),
    a = document.createElement('a');
    a.download = "test.json";
    a.href = window.URL.createObjectURL(blob);
    a.dataset.downloadurl = ['text/json', a.download, a.href].join(':');
    e.initEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
    a.dispatchEvent(e);
}

将其封装到 Electron 应用中并使用 node fs 模块保存文件

saveFile 函数的改变

saveFile: function() {
    const data = JSON.stringify(this.arr)
    const fs = require('fs');
    try { fs.writeFileSync('myfile.txt', data, 'utf-8'); }
    catch(e) { alert('Failed to save the file !'); }
}

然后用Electron 包裹起来

electron ./index.html

【讨论】:

  • 很高兴能为您提供帮助。如果可能,请接受我的回答
  • 也许有点迂腐,但是为什么要费力创建一个链接元素然后触发点击它,而没有它就很容易触发下载。解决方案似乎真的很脆弱。
  • @Hybridwebdev 你也可以使用这个库来保存文件。 github.com/eligrey/FileSaver.js/edit/master/src/FileSaver.js。它也使用 a.href 和 click 事件。或者你可以使用下载 API 但 Edge 不支持 developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/…
  • 你能解释一下如何用电子包装吗?我对电子一无所知。我想为 yii2 gii 之类的 vue js 编写一个 crud 代码生成器,但我不知道用 vue 和 js 为本地项目创建目录或生成文件
  • 制作一个电子应用程序只是为了让用户下载一些东西,这对我来说似乎是严重的矫枉过正。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-19
  • 2020-07-18
  • 1970-01-01
  • 2017-06-29
相关资源
最近更新 更多