需求: 在项目中,有时候可能在不同画面需要完成同一功能,比如示例文件列表查看功能,系统上传文件,需要查看文件列表,以及文件历史记录
话不多说,上图
这个查看文件的Dialog需要在系统中的很多地方调用,开发过程中不可能在每个地方都定义一遍,那么,我们可能使用自定义控件形式,代码如下
<template> <el-dialog title="查看文件" :visible.sync="innerVisible" class="form-dialog" center @closed="onClosed"> <el-tabs v-model="activeName" @tab-click="handleClick"> <el-tab-pane label="文件列表" name="fileList"> <el-table v-loading="listLoading" size="small" :data="list" style=" 100%" element-loading-text="Loading" border stripe fit highlight-current-row > <el-table-column label="序号" align="center"> <template slot-scope="scope"> {{ scope.$index + 1 }} </template> </el-table-column> <el-table-column label="文件名" align="center"> <template slot-scope="scope"> {{ scope.row.name }} </template> </el-table-column> <el-table-column label="文件大小(KB)" align="center"> <template slot-scope="scope"> <span>{{ scope.row.size }}</span> </template> </el-table-column> <el-table-column label="操作" align="center"> <template slot-scope="scope"> <el-button size="mini" @click="downLoadFile(scope.row)">下载</el-button> </template> </el-table-column> </el-table> </el-tab-pane> <el-tab-pane label="历史版本" name="history"> <el-table v-loading="historyListLoading" size="small" :data="historyList" style=" 100%" element-loading-text="Loading" border stripe fit highlight-current-row > <el-table-column label="序号" align="center"> <template slot-scope="scope"> {{ scope.$index + 1 }} </template> </el-table-column> <el-table-column label="时间" align="center"> <template slot-scope="scope"> {{ scope.row.Date | parseTime('{y}-{m}-{d} {h}:{i}') }} </template> </el-table-column> <el-table-column label="备注" align="center"> <template slot-scope="scope"> <span>{{ scope.row.Remark }}</span> </template> </el-table-column> <el-table-column label="操作" align="center"> <template slot-scope="scope"> <el-button size="mini" @click="downLoadVersionFile(scope.row)">下载</el-button> </template> </el-table-column> </el-table> </el-tab-pane> </el-tabs> <div slot="footer" class="dialog-footer"> <el-button type="primary" @click="innerVisible = false">确定</el-button> </div> </el-dialog> </template> <script> import { fileDownload, getFileList, getFileHistoryList, versionFileDownload } from '@/api/common/common' import { getToken } from '@/utils/auth' import { parseTime, downloadFile } from '@/utils' export default { name: 'FileListDialog', filters: { parseTime(time, cFormat) { return parseTime(time, cFormat) } }, components: { }, props: { visible: { type: Boolean, default: false }, url: { type: String, default: '' } }, data() { return { token: getToken(), list: null, historyList: null, listLoading: true, historyListLoading: true, innerVisible: this.visible, sURL: '', activeName: 'fileList' } }, watch: { visible(val, oldVal) { if (val === oldVal) { return } this.innerVisible = val }, innerVisible(val, oldVal) { if (val === oldVal) { return } this.$emit('update:visible', val) }, sURL(val, oldVal) { if (val === oldVal) { return } this.activeName = 'fileList' // 获取数据 this.getList() } }, mounted() {}, updated() { this.sURL = this.url this.dVisible = this.dialogFormVisible }, methods: { handleClick(tab, event) { switch (tab.name) { case 'fileList': this.getList() break case 'history': this.getHistory() break } }, getList() { this.listLoading = true var param = { url: this.sURL, token: getToken() } getFileList(param).then(response => { this.list = response.data this.listLoading = false }) }, getHistory() { this.historyListLoading = true var param = { url: this.sURL, token: getToken() } getFileHistoryList(param).then(response => { this.historyList = response.data this.historyListLoading = false }) }, onClosed() { this.sId = '' }, downLoadFile(row) { var param = { token: getToken(), url: row.url } fileDownload(param).then(res => { if (res.code === 20000) { downloadFile(res.data.name, res.data.dataStr) } }) }, downLoadVersionFile(row) { var param = { token: getToken(), url: row.URL, versionNo: row.VersionNo } versionFileDownload(param).then(res => { if (res.code === 20000) { downloadFile(res.data.name, res.data.dataStr) } }) } } } </script> <style></style>
其中,Dialog控制显隐的关键部分是watch函数部分
visible(val, oldVal) { if (val === oldVal) { return } this.innerVisible = val }, innerVisible(val, oldVal) { if (val === oldVal) { return } this.$emit('update:visible', val) }
visible和innerVisible分别对应控件的属性以及Data,防止多次修改属性问题。
sURL(val, oldVal) { if (val === oldVal) { return } this.activeName = 'fileList' // 获取数据 this.getList() }
该部分是控制Dialog显示数据用
父画面调用:
<template> <div class="app-container"> <div class="filter-container"> <el-button v-waves size="small" class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">搜索</el-button> </div> <el-table v-loading="listLoading" size="small" :data="list" style=" 100%" element-loading-text="Loading" border stripe fit highlight-current-row > <el-table-column label="技术协议" align="center"> <template slot-scope="scope"> <el-button size="mini" @click="viewFile(scope.row)">查看</el-button> </template> </el-table-column> </el-table> <Pagination v-show="total > 0" size="small" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" /> <FileListDialog :url="fileURL" :visible.sync="fileListDialogVisible" /> </div> </template> <script> import FileListDialog from './dialog/fileListDialog.vue' export default { components: { FileListDialog }, data() { return { fileURL: '', fileListDialogVisible: false } }, methods: { viewFile(row, type) { if (stringIsNullOrEmpty(row.Path)) return this.fileListDialogVisible = true this.fileURL = row.Path // URL地址 } } } </script>