一、http-vue-loader.js
http-vue-loader.js 是一个 Vue 单文件组件加载器,可以让我们在传统的 HTML 页面中使用 Vue 单文件组件,而不必依赖 Node.js 等其他构建工具。它内置了 Vue.js 和样式加载器,并能自动解析 Vue 单文件组件中的所有内容,并将其转化为 JavaScript 代码。
ps :注意:httpVueLoader 加载的单文件导出方式不同:module.exports = {},而不是 export default {}
二、示例
这里对了 elementUI 的上传组件做一个封装,使其能可根据业务来配置上传的附件
2.1. vue 组件
<template>
<div>
<el-col :span="24" v-for="(template,index) in uploadsTemplates">
<el-card style="margin-top: 20px;">
<div slot="header" class="clearfix">
<el-row style="display: flex;align-items: center;">
<el-col :span="20"><span style="font-size: 16px;">{{template.title}}</span></el-col>
<el-col :span="4" style="text-align: right;">
<el-tag v-if="template.required == 'N'" type="info">非必上传</el-tag>
<el-tag v-if="template.required == 'Y'" type="danger">必须上传</el-tag>
</el-col>
</el-row>
</div>
<p style="color: #F56C6C;margin-bottom: 5px;">
{{template.description}}
</p>
<el-col :span="12" style="padding: 20px 0 ">
<el-form-item prop="requiredFile"
ref="uploadFormItems"
:rules="template.success||template.required=='N'?[]:[{required: true, message: '请上传必要件', trigger: 'blur'}]">
<el-row>
<el-upload :auto-upload="true"
drag
:file-list="template.fileList"
ref="uploadComponents"
name="attachment"
:on-preview="(file)=>onPreview(file,template)"
:before-upload="(file)=>onBeforeUpload(file,template)"
:on-success="(response,file,fileList)=>onUploadSuccess(response,file,fileList,index)"
:on-remove="(file,fileList)=>onRemoveFile(file,fileList,index,template)"
:action="uploadsUrl"
:data="{ywlx:ywlx,applyNo:applyNo,configId:template.configId}"
multiple>
<i class="el-icon-upload"></i>
<div>将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">{{msg}}</div>
</el-upload>
</el-row>
</el-form-item>
</el-col>
</el-card>
</el-col>
<div class="demo-image__preview" style="display: none">
<el-image
style="width: 100px; height: 100px"
ref="imagePreview"
:src="previewSrc"
:preview-src-list="previewSrcList">
</el-image>
</div>
</div>
</template>
<script>
module.exports = {
name: "upload-template",
props: ['contextPath', 'applyNo', 'ywlx', 'fromedit','msg','beforeUpload'],
data() {
return {
uploadsUrl: this.contextPath + "/system/sysUploadFile/uploadAttachment",
//预览图片弹窗
imgDialogVisible: false,
//预览图片路径
previewSrc: '',
//预览图片集合
previewSrcList: [],
// 要件(只是校验用)
requiredFile: [],
//上传模板
uploadsTemplates: [],
//上传前钩子
onBeforeUpload: this.beforeUpload
}
},
mounted: function () {
if(this.onBeforeUpload == null){
this.onBeforeUpload = (file,upload)=>{
return true;
}
}else{
if (typeof this.onBeforeUpload === 'function') {
} else {
throw new Error('beforeUpload is not a function');
}
}
// 读取附件模板
$.ajax({
type: "get",
async: false,
url: this.contextPath + '/system/sysUploadConfig/getUploadsTemplates',
data: {ywlx: this.ywlx},
dataType: "json"
}).then((response) => {
if (response.code == 0) {
response.data.forEach(template => {
template.success = false;
template.fileList = [];
});
this.uploadsTemplates.push(...response.data);
if (this.fromedit) {
$.ajax({
type: "post",
async: false,
url: this.contextPath + "/system/sysUploadFile/getFilesByApplyNo",
dataType: "json",
data: {ywlx:this.ywlx,applyNo: this.applyNo}
}).then((response) => {
if (response.code == 0) {
response.data.forEach(attachemnt => {
this.uploadsTemplates.forEach(template => {
if (attachemnt.configId === template.configId) {
template.fileList.push(attachemnt);
template.success = true;
}
})
});
} else {
this.$message({
showClose: true,
message: response.msg,
type: 'error',
offset: 200,
duration: 10000
});
console.log("error:");
console.log(response);
}
});
}
} else {
this.$message({
showClose: true,
message: response.msg,
type: 'error',
offset: 200,
duration: 10000
});
console.log("error:");
console.log(response);
}
});
},
methods: {
//预览图片
onPreview: function (file, template) {
this.previewSrc = this.contextPath+(file.url?file.url:file.response.data.url);
template.fileList.forEach((file)=>{
this.previewSrcList.push(this.contextPath+(file.url?file.url:file.response.data.url));
});
console.log(this.previewSrc)
console.log(this.previewSrcList)
this.$refs.imagePreview.clickHandler();
},
//文件上传成功的回调
onUploadSuccess: function (response, file, fileList, index) {
console.log('上传成功需要操作请增加事件:upload-success')
if (response.code == 0) {
// 把要件列表中的当前这个要件的success置为true
this.uploadsTemplates[index].success = true;
this.uploadsTemplates[index].fileList = fileList;
}else {
this.$message({
showClose: true,
message: response.msg,
type: 'error',
offset: 200,
duration: 2000
});
//删除控件里某个文件
fileList.splice(fileList.indexOf(file),1);
}
this.$emit('upload-success',response)
//清除控件里所有文件
// this.$refs.uploadComponents[index].clearFiles();
},
//移除某个文件
onRemoveFile: function (file, fileList, index, upload) {
//调用远程移除附件,传递file.fileId
$.ajax({
url: this.contextPath + '/system/sysUploadFile/removeAttachment',
method: 'post',
async: false,
data: {fileId: file.fileId?file.fileId:file.response.data.fileId}
}).then((response) => {
if (response.code == 0) {
this.uploadsTemplates[index].fileList = fileList;
// 如果已经全部移除,加上校验
if(fileList.length===0){
this.uploadsTemplates[index].success = false;
}
} else {
console.log("error message:");
console.log(response.data);
this.$message({
showClose: true,
message: response.msg,
type: 'error',
offset: 200,
duration: 2000
});
}
});
},
},
}
</script>
<style scoped>
.el-upload__input{
display: none;
}
</style>
2.2. html 页面
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('新增上传文件信息')" />
<th:block th:include="include :: element-ui('新增上传文件信息')" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content" id="upload-test-form">
<div class="row">
<el-form ref="uploadForm" id="uploadForm" :model="applyForm">
<upload-template :apply-no="applyForm.applyNo"
:context-path="ctx"
:before-upload="beforeUpload"
@upload-success="uploadSuccess"
ywlx="ywlx1"></upload-template>
</el-form>
</div>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: element-ui-js" />
<script th:src="@{/lib/http-vue-loader.js}"></script>
<script th:inline="javascript">
var prefix = ctx + "system/sysUploadFile";
var vm = new Vue({
el: "#upload-test-form",
components: {
// 将组建加入组建库
'upload-template': httpVueLoader(ctx+'components/upload-template.vue'),
},
data: {
ctx:ctx,
applyForm: {
ywlx:"ywlx1",
applyNo:"123456789",
},
},
methods: {
beforeUpload: function(file,template){
console.log("上传前操作")
console.log(file)
console.log(template)
//返回 true,继续上传,返回false,终止上传
return false;
},
uploadSuccess: function(file){
console.log("上传成功操作")
console.log(file)
}
}
});
function submitHandler() {
vm.$refs.uploadForm.validate((valid) => {
if (valid) {
alert('文件验证通过!');
} else {
alert('文件验证失败!');
}
});
}
</script>
</body>
</html>
3.3. 效果
业务类型上传文件配置
业务上传附件页面
保存的文件
总结:
通过 http-vue-loader.js,我们可以在普通的 HTML 页面中使用 Vue 单文件组件来实现前端开发的快速迭代。在使用 http-vue-loader.js 时,我们需要引入 Vue.js 和 http-vue-loader.js,并使用 httpVueLoader () 方法加载 Vue 单文件组件,并将其实例化为 Vue 对象。