今天继续分享 Vue.js 学习笔记,上传文件,并显示在下拉框列表中。
前面基础的如何使用 Flask + VUE 搭建环境等知识,可以戳这里查看。
下面我们直接进入主题
显示本地文件
首先,我们要有一个后台接口,来获取到指定目录下的文件。例如如果我们想获取目录下的 xlsx 文件,那么可以编写代码如下:
class FileListView(Resource): def get(self): files = os.listdir(PY_DIR) file_list = [] i = 0 for f in files: file_dict = {} if f[-4:] == 'xlsx': file_dict["value"] = i file_dict["label"] = f file_list.append(file_dict) i += 1 return {'code': 200, 'data': file_list} api_data.add_resource(FileListView, '/filelist')
使用 flask_restful 来驱动,并封装数据成 {“value”:“”, “label”:“”} 的形式,用于 VUE 前台渲染时使用。
接下来,我们在前端代码中,创建一个 index.vue 文件,添加一个下拉框控件
<template> <div> <el-select id="file" v-model='fname' filterable placeholder="选择已有" v-on:focus="getData()"> <el-option v-for="item in files" :key="item.value" :label="item.label" :value="item.label"> </el-option> </el-select> <input type="hidden" name="middata" id="middata"> </div> </template>
我们加了一个 select 组件,并使用 element UI 官方的方法来渲染数据,即:
v-for="item in files"
:key="item.value"
:label="item.label"
:value="item.label"
机智的你可能注意到了 v-on:focus="getData()",这个是当输入下拉框组件获取焦点时,会再次调用 getData 函数,用来更新数据。
下面我们再看下 script 部分
<script> import dealdata from '../../api/data.js' export default { data() { return { depatment:'', files:[], vals:0, fname: '', //fileList: [{name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}] } }, mounted() { this.getData(); }, methods: { getData:function(){ dealdata.getfile() .then(res => { if(res.data.code == 200) { if (res.data.data.length == 0){ this.files = [] }else{ this.files = res.data.data; } }else{ console.log("API 调用错误"); } }) .catch(function(error){ console.log("网络错误"); }) } } } </script>
定义了 getData 这个函数,用于调用后台 API
可以看到,我这里是使用 dealdata =>(import dealdata from '../../api/data.js') 来处理网络请求的,这其实就是一个封装好了的 axios,这样每次调用网络 API 时就方便很多了。
下面我们就来看看当前的效果:
上方的两个 button 先忽略,我们后面再添加
选择时的效果:
下拉框的数据,当然就是 PY_DIR 中的文件名啦。
上传文件
一样的,我们要先有个 API 接口
from flask import request class UploadandSaveFileView(Resource): def post(self): if request.method == 'POST': f = request.files['file'] # file_name = secure_filename(f.filename) # f.save(PYTEST_DIR + '\\' + file_name) f.save(os.path.join(PY_DIR, f.filename)) return {"code": 201, "content": "upload success"} api_data.add_resource(UploadandSaveFileView, '/upload')
感兴趣的同学可以试试 secure_filename 函数,看看保存出来的文件名有什么区别。
接下来我们添加组件到页面
<el-upload class="upload-demo" accept=".xlsx" ref="upload" action="http://127.0.0.1:9980/api/upload" :on-preview="handlePreview" :on-remove="handleRemove" :on-exceed="handleExceed" :on-success="handleSuccess" :on-error="handleError" :limit="1" :auto-upload="false"> <el-button slot="trigger" size="small" type="primary">选取文件<i class="el-icon-upload el-icon--right"></i></el-button> <el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">上传到服务器</el-button> <div slot="tip" class="el-upload__tip">选择用例文件,只支持上传xlsx格式</div> </el-upload>
使用 element UI 提供的原生组件 el-upload,其中有些属性还是要好好理解的。
action:就是上传的地址
on-preview:点击已经上传的文件时调用
on-success:文件上传成功时调用
其余的属性和方法等,大家可以到官网上查看,都写的很清楚了。
下面我们看看 script 部分,在 methods 部分添加函数
submitUpload() { if(file.name = ' '){ this.$message.warning(`请选择一个文件`) } else{ this.$refs.upload.submit(file.name); console.log("Submit");} }, handleRemove(file, fileList) { console.log(file, fileList); }, handlePreview(file) { console.log(file); console.log(file.name); }, handleSuccess(file) { this.$message.success(`上传成功`); this.$refs.upload.clearFiles(); }, handleError(file) { this.$message.error(`上传失败`); }, handleExceed(files, fileList) { this.$message.warning(`当前限制只能选择 1 个文件`); }
submitUpload 函数直接调用原生的 submit 方法,把文件上传到我们配置的地址上,它绑定的对象为 “上传到服务器” 这个 button 的点击事件。
handleSuccess 函数则时清空的已上传的文件列表。
这样,我们就完成了上传文件到服务器的功能,并且每次下拉列表里展示的文件,都是最新的文件列表哦。