有时我们需要从文件中读取数据. 在旧时代,你需要将其发送到服务器,然后返回所需的数据。
如果我们只是想读一个文本文件,以便在用户界面水平上做一些微妙的事情,我们不需要将文件发送到服务器。
使用 FileReader API
FileReader API 提供了一个很好的接口,可以通过使用 File或 Blob对象类型以不同的方式读取数据。
FileReader 实例有一个readAsText
方法,我们可以使用它来读取文件作为文本:
1const reader = new FileReader();
2reader.readAsText(file);
由于FileReader API是无同步的,它暴露了我们可以使用的几个事件来获取其状态,特别是,我们需要上载
事件来访问文件读完后的数据:
1const reader = new FileReader();
2reader.onload = e => console.log(e.target.result);
3
4reader.readAsText(file);
正如您所看到的,文本数据可通过e.target.result
访问。
文件阅读器组件
以前的代码已经读到一个文件,但我们仍然必须给它文件对象. 为此,我们必须使用一个<input type="file">
HTML标签,这会触发一个更改
事件,我们可以通过ev.target.files
访问该文件。
让我们创建一个 FileReader.vue 组件,将其全部放在一起:
1[label FileReader.vue]
2<template>
3 <label class="text-reader">
4 <input type="file" @change="loadTextFromFile">
5 </label>
6</template>
7
8<script>
9export default {
10 methods: {
11 loadTextFromFile(ev) {
12 const file = ev.target.files[0];
13 const reader = new FileReader();
14
15 reader.onload = e => this.$emit("load", e.target.result);
16 reader.readAsText(file);
17 }
18 }
19};
20</script>
组件正在发出一个负载
事件,以便母组件可以处理数据。
使用组件
考虑到您已经安装了 App.vue 组件,让我们使用它来演示我们的组件:
1[label App.vue]
2<template>
3 <div id="app">
4 <textarea rows="10" v-model="text"></textarea>
5 <br>
6 <text-reader @load="text = $event"></text-reader>
7 </div>
8</template>
9
10<script>
11import FileReader from "./FileReader";
12
13export default {
14 name: "app",
15 data: () => ({ text: "" }),
16 components: {
17 FileReader
18 }
19};
20</script>
我们需要添加一个文本
数据属性,作为一个例子,将其绑定到使用v-model
的文本区域。
奖金:格式化文件按钮
在每个浏览器中,<input type="file">
标签的渲染方式不同. 如果我们想要一个自定义的风格,我们可以隐藏它,并代替它的<label>
标签。
要隐藏输入,请使用 opacity: 0;
css 属性. 使用 display: block;
或 visibility: hidden;
将破坏其可访问性。
我们还需要定位和z索引的组合,以便将其置于标签后面:
1[label FileReader.vue]
2<template>
3 <label class="text-reader">
4 Read File
5 <input type="file" @change="loadTextFromFile">
6 </label>
7</template>
8
9<style>
10.text-reader {
11 position: relative;
12 overflow: hidden;
13 display: inline-block;
14
15 /* Fancy button style 😎 */
16 border: 2px solid black;
17 border-radius: 5px;
18 padding: 8px 12px;
19 cursor: pointer;
20}
21.text-reader input {
22 position: absolute;
23 top: 0;
24 left: 0;
25 z-index: -1;
26 opacity: 0;
27}
28</style>
这应该是技巧,输入文件按钮应该完美地工作。
您可以在 This Codesandbox中看到代码和演示文稿。
保持冷静