技术选型
vue2element ui=>el-dialog
实现功能
封装一个导入与下载模板的dialog公共组件
策略使用目的
通过每一次引用创建一个相关配置文件进行配置管理,达到结构统一管理,拆分不同模块管理。 解决如下代码问题:
- 在封装的组件中每一次引用都加入几行相关配置的代码导致页面代码越来越臃肿
- 每一次使用时都从父组件中传入过多相关配置资料
文件结构
组件的引用
<ImportDialog ref="import" :from="'ThirdPartyToolsManagementAccount'" @childFilter="handleFilter()" />
import ImportDialog from '@/components/ImportDialog'
export default {
components: { ImportDialog },
}
ref 注册组件引用信息
from 指定引用来源
childFilter 回调导入成功刷新页面
组件绘制与相关功能文件(index.vue)
关键代码
const data = strategy(newV) // 根据父组件传入来源调用不同策略配置
<template>
<el-dialog
class="import-dialog"
:visible.sync="importVisible"
:title="title"
width="350px"
:close-on-click-modal="false"
:close-on-press-escape="false"
:before-close="handleImportClose"
>
<el-form>
<el-form-item label="导入文件">
<el-upload
ref="upload"
:action="uploadUrl"
:headers="myHeaders"
:auto-upload="false"
:limit="1"
:before-upload="handleBeforeUpload"
:on-exceed="handleExceed"
:on-error="handleError"
:on-success="handleSuccess"
>
<el-button
size="small"
type="primary"
plain
icon="el-icon-download"
>选择文件</el-button>
<div slot="tip" class="upload-tip">注意:仅支持 xlsx文件</div>
</el-upload>
</el-form-item>
<el-form-item label="点击下载">
<el-button type="text" class="download-button" @click="handleDownloadTemplate">模板</el-button>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="handleImportClose">取 消</el-button>
<el-button v-loading="importLoading" type="primary" @click="handleImportConfirmed">确 定</el-button>
</span>
</el-dialog>
</template>
<script>
import { downloadByATag } from '@/utils'
import { getToken } from '@/utils/auth'
import strategy from './strategy'
export default {
name: 'ImportDialog',
props: {
// 配置类型
from: {
type: String,
default: ''
}
},
data() {
return {
myHeaders: { Authorization: `Bearer ${getToken()}` },
importVisible: false,
importLoading: false,
title: '', // dialog标题
uploadUrl: '', // 上传url
tempRequest: null // 模板url
}
},
watch: {
from: {
handler(newV) {
if (newV) {
const data = strategy(newV) // 根据父组件传入来源调用不同策略配置
this.title = data.title
this.uploadUrl = data.uploadUrl
this.tempRequest = data.tempRequest
}
},
immediate: true
}
},
methods: {
// 导入弹窗展示
show() {
this.importVisible = true
},
// 导入窗口关闭
handleImportClose() {
this.importVisible = false
this.$refs.upload.clearFiles()
},
// 导入确认
handleImportConfirmed() {
if (this.$refs.upload.$refs['upload-inner'].fileList.length === 0) {
this.$message.error('请导入文件')
return
}
this.uploadLoading = true
this.$refs.upload.submit()
},
// 上传之前
handleBeforeUpload(file) {
const FileExt = file.name.replace(/.+\./, '')
if (['xlsx'].indexOf(FileExt.toLowerCase()) === -1) {
this.$message.error('文件格式有误,请重新上传')
return false
}
if (file.size > 1024 * 1024 * 10) {
this.$message.error('文件不能超过10MB')
return false
}
},
// 上传限制条件
handleExceed(files, fileList) {
this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)
},
// 上传成功
handleSuccess({ code, msg, data }, file, fileList) {
if (code === 1) {
this.handleImportClose()
this.$emit('childFilter')
if (!Array.isArray(data)) {
downloadByATag(data.url, data.name)
this.$message.error(data.msg)
} else {
this.$message.success('上传成功')
}
} else {
this.$message.error('上传失败')
}
this.importLoading = false
},
// 上传错误
handleError() {
this.$message.error('上传失败')
},
// 下载模板
handleDownloadTemplate() {
this.tempRequest().then(res => {
if (res?.code === 1) {
this.$message.success(res.msg)
} else {
this.$message.error(res.msg)
}
})
}
}
}
</script>
<style scoped>
.upload-tip{
color: red;
}
.download-button {
padding: 0 !important;
font-size: 14px !important;
}
.import-dialog .el-form-item {
margin-bottom: 0px;
}
</style>
策略入口文件(strategy.js)
根据不同的来源实例化不同的策略配置信息
import ThirdPartyToolsManagementBasic from './options/ThirdPartyToolsManagementBasic'
import ThirdPartyToolsManagementAccount from './options/ThirdPartyToolsManagementAccount'
/**
* 返回导入文件配置信息
* @param {String} from 配置来源
* @returns Object
*/
function strategy(from) {
let result = {}
switch (from) {
case 'ThirdPartyToolsManagementBasic':
result = new ThirdPartyToolsManagementBasic()
break
case 'ThirdPartyToolsManagementAccount':
result = new ThirdPartyToolsManagementAccount()
break
}
return result
}
export default strategy
策略配置文件(ThirdPartyToolsManagementAccount.js)
import { accountDataModelApi } from '@/api/accountInfo'
/**
* 账号 - 账号信息 - 第三方支付工具 - 账号及店铺资料
*/
class ThirdPartyToolsManagementAccount {
constructor() {
this.title = '批量导入账号店铺资料'
this.uploadUrl = '/api/v1/admin/account/third-party-tool/account-shop-import'
this.tempRequest = accountDataModelApi
}
}
export default ThirdPartyToolsManagementAccount