2021SC@SDUSC
目录
本次分析“系统设置”中的“文件管理”界面,如下:
页面总体源码
页面对应的源码在src/views/file-management/index.vue。大体源码如下:
<template>
<anji-crud ref="listPage" :option="crudOption">
<template v-slot:buttonLeftOnTable>
<el-upload
class="el-upload"
ref="upload"
:action="uploadUrl"
:headers="headers"
:on-success="handleUpload"
:on-error="handleError"
:show-file-list="false"
:limit="1"
>
<el-button
type="primary"
icon="el-icon"
v-permission="'fileManage:upload'"
>文件上传</el-button
>
</el-upload>
</template>
<template slot="edit" slot-scope="props">
<el-button type="text" @click="copyUrlPath(props)">复制url</el-button>
</template>
<template slot="rowButton" slot-scope="props">
<el-button type="text" @click="customButtom(props)">下载</el-button>
</template>
</anji-crud>
</template>
这个页面仍然使用了之前分析过的anji-crud自定义组件
文件上传
这部分是通过el-button实现的,当我们点击按钮并上传文件后,会调用文件上传的回调函数,此函数源码如下:
handleUpload(response, file, fileList) {
console.log(this);
this.$refs.listPage.handleQueryForm();
this.$refs.upload.clearFiles();
},
handleError() {
this.$message({
message: "上传失败!",
type: "error"
});
},
第一个函数是上传成功的回调,第二个函数是上传失败的的回调。当上传成功时,会执行:
this.$refs.listPage.handleQueryForm();
来触发查询按钮,以实现上传后的图片能够立刻展示的效果。通过源码发现,这个listPage就是anji-crud的ref属性的值,而handleQueryForm()函数是anji-crud组件的方法。此方法源码如下:
handleQueryForm(from) {
if (from == "query") {
if (this.hasTreeFieldInQueryForm) {
delete this.queryParams[this.queryFormTreeField.field];
}
}
if (from == "tree") {
if (this.hasTreeFieldInQueryForm) {
var treeVal = this.queryParams[this.queryFormTreeField.field];
this.queryParams = {
pageNumber: 1,
pageSize: 10
};
this.queryParams[this.queryFormTreeField.field] = treeVal;
}
}
// 默认的排序
if (
this.isBlank(this.queryParams["order"]) &&
this.isNotBlank(this.option.buttons.query.order)
) {
this.queryParams["sort"] = this.option.buttons.query.sort;
this.queryParams["order"] = this.option.buttons.query.order;
}
this.queryParams.pageNumber = 1;
this.handleQueryPageList();
},
我们调用此函数的无参函数,即展示默认的排序。此方法最后调用了handleQueryPageList()函数,源码如下:
async handleQueryPageList() {
var params = this.queryParams;
const { data, code } = await this.option.buttons.query.api(params);
if (code != "200") return;
this.records = data.records;
this.total = data.total;
},
可以看到此方法调用了api中的查询方法,await 用于等待一个异步方法执行完成。方法最后将返回值data赋值给total变量,从而实现展示数据的效果。
综上流程:点击“文件上传”按钮并上传--》触发回调函数hanlerUpload--》执行handlerQueryForm的无参函数--》调用handlerQueryPageList--》调用异步方法返回结果--》展示数据。
复制url
复制url对应代码如下:
<template slot="edit" slot-scope="props">
<el-button type="text" @click="copyUrlPath(props)">复制url</el-button>
</template>
点击后调用copyUrlPath方法,源码如下:
copyUrlPath(val) {
this.copyToClip(val.msg.urlPath);
this.$message({
message: "已将url路径复制至剪切板!",
type: "success"
});
},
copyToClip(content, message) {
var aux = document.createElement("input");
aux.setAttribute("value", content);
document.body.appendChild(aux);
aux.select();
document.execCommand("copy");
document.body.removeChild(aux);
}
copyUrlPath方法又调用了copyToClip方法,这里我们重点分析复制的实现,即如何实现点击之后等同于执行了ctrl-c操作。
通过查询资料得知,前端实现拷贝操作主要有四种方式:ZeroClipboard,Clipboard.js,execCommand,setData。源码中使用的是execCommand。此方法具体步骤如下:
1. 通过document.createElement方法新创建一个input框aux,这个input框就是我们要复制的内容的容器。这里有几个坑:input框不能有disabled属性;input的width || height 不能为0;input框不能有hidden、display:none属性。所以我们才自己新创建一个input框,因为源码中的inpu框是由各种样式的。
2. 将aux的值设置为我们传进来的值,即content,这就是我们要复制的内容。
3. 调用aux.select()
4. 接下来就可以直接使用execCommand("copy")来进行拷贝,之后移除aux即可。