之前一直使用upload組件單個上傳文件,最近遇到需要上傳表單字段,表單中有多個參數
下圖是接口要求:
官網上傳組件中提供了響應的功能實現,但是demo中未演示,不注意看文檔參數的話,可能會不知道這個:
接受一個object來作爲參數傳遞,
我的組件這麼寫:
<el-upload
class="upload-demo"
drag
name="file"
:limit="1"
:data="insertProgram"
:on-exceed="handleFileOneExceed"
:before-upload="beforeFileUpload"
:on-success="handleFileSuccess"
:on-remove="handleFileRemove"
:file-list="fileList"
:action="requestAddProgram">
<i class="el-icon-upload"></i>
<div class="el-upload__text">將文件拖到此處,或<em>點擊上傳</em></div>
<div class="el-upload__tip" slot="tip">只能上傳txt文件,格式範例:文件名爲時間如:2020-03-02.txt,內容:23:00 晚間新聞</div>
</el-upload>
data中:
data () {
return {
insertProgram: {
liveId: 0
}
}}
這樣就將file 以及參數作爲表單傳送
上傳作爲mixins引入:
import {requestUploadImg} from '@/api/api'
// 混入對象上傳組件。直接混入,需要覆蓋上傳成功後的回調
/* <el-upload
class="upload-demo"
drag
name="img"
:limit="1"
:on-exceed="handleFileOneExceed"
:on-success="handleFileSuccess"
:on-remove="handleFileRemove"
:file-list="fileList"
:action="requestUploadFile">
<i class="el-icon-upload"></i>
<div class="el-upload__text">將文件拖到此處,或<em>點擊上傳</em></div>
<!-- <div class="el-upload__tip" slot="tip">只能上傳jpg/png文件,且不超過500kb</div>-->
</el-upload> */
// 混入組件需要監聽 uploadFileList
const fileUpload = {
data () {
return {
requestUploadFile: requestUploadImg,
fileList: [],
uploadFileList: []
}
},
methods: {
beforeFileUpload (file) {
const isTXT = file.type.indexOf('text') > -1
if (!isTXT) {
this.$message.error('請選擇txt文件')
}
return isTXT
},
handleFileOneExceed (files, fileList) {
this.$message.warning('禁止上傳多個文件')
},
handleFileRemove (file, fileList) {
this.uploadFileList.splice(this.uploadFileList.findIndex(item => item === file.response.body), 1)
},
handleFileSuccess (res, file) {
this.uploadFileList.push(res.body)
this.$notify.success({
title: '成功',
message: '文件上傳成功'
})
}
}
}
export default fileUpload
這個組件全部代碼爲:(可以只看關心部分的代碼):
<template>
<div>
<div class="model-top">
<span class="model-title">頻道管理</span>
<div>
<el-button type="primary" @click="openAddSource">新增</el-button>
<el-select v-model="channelSearchForm.status" placeholder="請選擇">
<el-option
v-for="item in channelStatus"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<el-input placeholder="搜索關鍵詞" v-model="channelSearchForm.title" class="model-input">
<el-button slot="prepend" icon="el-icon-search"></el-button>
</el-input>
</div>
</div>
<div>
<div>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
type="index"
label="序號">
</el-table-column>
<el-table-column
prop="title"
label="標題">
</el-table-column>
<el-table-column
prop="coverUrls"
label="封面"
width="150">
<template slot-scope="scope">
<el-carousel height="100px" indicator-position="none">
<el-carousel-item v-for="(item,index1) in scope.row.coverUrls.split(',')" :key="index1">
<el-image
style="width: 150px;height: 100%;"
:src="item"
fit="contain">
</el-image>
</el-carousel-item>
</el-carousel>
</template>
</el-table-column>
<el-table-column
prop="description"
label="描述">
</el-table-column>
<el-table-column
prop="type"
label="類型">
<template slot-scope="scope">
<span>{{initShowType(scope.row.type)}}</span>
</template>
</el-table-column>
<el-table-column
prop="source"
label="來源">
</el-table-column>
<el-table-column
prop="createTime"
label="創建時間">
</el-table-column>
<el-table-column
prop="linkUrl"
label="鏈接地址">
</el-table-column>
<!--<el-table-column
prop="beginTime"
label="開始時間">
</el-table-column>
<el-table-column
prop="endTime"
label="結束時間">
</el-table-column>-->
<el-table-column
prop="status"
label="狀態">
</el-table-column>
<el-table-column
prop="uploader"
label="上傳人">
</el-table-column>
<el-table-column
label="操作">
<template slot-scope="scope">
<el-button type="text" @click="openProgram(scope.row.id)">查看節目單</el-button>
<el-button type="text" @click="openInsertProgram(scope.row.id)">插入節目單</el-button>
<el-button type="text" @click="openUpdateSource(scope.row)">修改</el-button>
<el-button type="text"
@click="updateSourceStatus(scope.row.id,'審覈通過')"
:disabled="scope.row.status === '已發佈' || scope.row.status === '審覈通過' ">通過
</el-button>
<el-button type="text"
@click="updateSourceStatus(scope.row.id,'未通過')"
:disabled="scope.row.status === '未通過' || scope.row.status === '已發佈' ">拒絕
</el-button>
<el-button type="text" @click="deleteSource(scope.row.id)">刪除</el-button>
</template>
</el-table-column>
</el-table>
<div class="model-pagination">
<el-pagination
:current-page.sync="channelSearchForm.pageNumber"
:page-size="channelSearchForm.pageSize"
background
layout="total, prev, pager, next"
:total="pageTotal">
</el-pagination>
</div>
</div>
</div>
<el-dialog :title="dialogTitle" :visible.sync="dialogAddMediaVisible" width="30%" @close="handleDialogClose">
<el-form :model="channelForm" ref="channelForm" label-position="top" :rules="rules">
<el-form-item label="標題:" prop="title">
<el-input v-model="channelForm.title" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="描述:" prop="description">
<el-input v-model="channelForm.description" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="封面:" prop="coverUrls">
<el-upload
ref="uploadAvatar"
class="avatar-uploader"
name="img"
:action="requestUploadImg"
list-type="picture-card"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
:on-preview="handlePictureCardPreview"
:file-list="imgList"
:on-remove="handleAvatarRemove">
<i class="el-icon-plus"></i>
</el-upload>
</el-form-item>
<el-form-item label="頻道地址:" prop="linkUrl">
<el-input v-model="channelForm.linkUrl" autocomplete="off" placeholder="請輸入頻道地址"></el-input>
</el-form-item>
<el-form-item label="頻道上傳人:" prop="uploader">
<el-input v-model="channelForm.uploader" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="頻道來源:" prop="source">
<el-input v-model="channelForm.source" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogAddMediaVisible = false">取 消</el-button>
<el-button type="primary" @click="onSubmit">確 定</el-button>
</div>
</el-dialog>
<el-dialog title="插入節目單" :visible.sync="dialogAddProgramVisible" width="30%">
<el-upload
class="upload-demo"
drag
name="file"
:limit="1"
:data="insertProgram"
:on-exceed="handleFileOneExceed"
:before-upload="beforeFileUpload"
:on-success="handleFileSuccess"
:on-remove="handleFileRemove"
:file-list="fileList"
:action="requestAddProgram">
<i class="el-icon-upload"></i>
<div class="el-upload__text">將文件拖到此處,或<em>點擊上傳</em></div>
<div class="el-upload__tip" slot="tip">只能上傳txt文件,格式範例:文件名爲時間如:2020-03-02.txt,內容:23:00 晚間新聞</div>
</el-upload>
</el-dialog>
<el-drawer
title="節目單"
:visible.sync="programVisible">
<el-form style="margin: 20px">
<el-form-item label="日期選擇:">
<el-date-picker
v-model="dataValue"
value-format="yyyy-MM-dd"
type="date"
range-separator="至"
start-placeholder="開始時間"
end-placeholder="結束時間">
</el-date-picker>
</el-form-item>
</el-form>
<div class="program-list">
<el-timeline>
<el-timeline-item
v-for="(item, index) in programList"
:key="index"
icon="el-icon-video-camera"
size="large"
color="#0bbd87"
:timestamp="item.beginTime">
{{item.programName}}
</el-timeline-item>
</el-timeline>
</div>
</el-drawer>
</div>
</template>
<script>
import {
requestSourceList,
requestUpdateSourceStatus,
requestDeleteSource,
requestAddSource,
requestUpdateSource,
requestProgramList,
requestAddProgram
} from '@/api/api'
import paging from '@/mixins/paging'
import commonData from '@/mixins/commonData'
import rules from '@/mixins/rules'
import imageUpload from '@/mixins/imageUpload'
import fileUpload from '@/mixins/fileUpload'
export default {
name: 'index',
mixins: [paging, commonData, rules, imageUpload, fileUpload],
data () {
return {
insertProgram: {
liveId: 0
},
requestAddProgram: requestAddProgram,
dialogAddProgramVisible: false,
programList: [
{
id: 0,
liveId: 0,
programName: '',
programDate: '',
beginTime: ''
}
],
programVisible: false,
dialogTitle: '新增頻道數據',
dataValue: this.dateFormatter(new Date(), false),
isEdit: false,
initLinkUrlMethods: [
{
label: 'upload',
value: '上傳資源'
}, {
label: 'input',
value: '輸入地址'
}
],
selectMethod: 'input',
programForm: {
liveId: 0,
beginDate: '',
endDate: ''
},
channelForm: {
id: -1,
title: '',
description: '',
coverUrls: '',
linkUrl: '',
type: 'live',
uploader: '',
source: ''
},
dialogAddMediaVisible: false,
tableData: [
{
createTime: '2020-03-02 16:25:09', // 創建時間
uploader: 'liwenbo', // 上傳人
linkUrl: '5,', // 連接地址
description: '河北送來蔬菜和水果1', // 描述
id: 17, // 資源標識符Id
coverUrls: '3,4,5', // url,url,url
source: '新華日報', // 來源
/* beginTime: '2020-01-02 12:00:12', // 活動類型的顯示開始時間
endTime: '2020-02-02 12:23:12', // 活動類型結束時間 */
title: '一方有難,八方支援!!',
type: 'activity', //
status: '待審覈'// 資源狀態
}
],
// 待審覈,審覈通過,未通過,已發佈
channelStatus: [
{
value: '',
label: '全部'
},
{
value: '待審覈',
label: '待審覈'
}, {
value: '審覈通過',
label: '審覈通過'
}, {
value: '未通過',
label: '未通過'
}
]
}
},
mounted () {
this.getSourceList()
},
watch: {
// 分頁在此已包含
channelSearchForm: {
handler: function (val, oldVal) {
this.getSourceList()
},
deep: true
},
coverImgList: function (newVal, oldVal) {
this.channelForm.coverUrls = newVal.join(',')
},
dataValue: {
handler: function (newVal, oldVal) {
this.programForm.beginDate = newVal
this.programForm.endDate = newVal
},
immediate: true
},
programForm: {
handler: function (newVal, oldVal) {
this.getProgramList()
},
deep: true
}
},
methods: {
openInsertProgram (id) {
this.insertProgram.liveId = id
this.dialogAddProgramVisible = true
},
openProgram (id) {
this.programForm.liveId = id
this.programVisible = true
},
addProgram () {
requestAddProgram().then(data => {
if (data.status === 200) {
console.log(data.body)
} else {
this.$notify.error({
title: '失敗',
message: '上傳節目單失敗'
})
}
})
},
getProgramList () {
requestProgramList({params: this.programForm}).then(data => {
if (data.status === 200) {
this.programList = data.body
} else {
this.$notify.error({
title: '失敗',
message: '獲取節目單失敗'
})
}
})
},
dateFormatter (str) { // 默認返回yyyy-MM-dd HH-mm-ss
let hasTime = arguments[1] !== false// 可傳第二個參數false,返回yyyy-MM-dd
let d = new Date(str)
let year = d.getFullYear()
let month = (d.getMonth() + 1) < 10 ? '0' + (d.getMonth() + 1) : (d.getMonth() + 1)
let day = d.getDate() < 10 ? '0' + d.getDate() : d.getDate()
let hour = d.getHours() < 10 ? '0' + d.getHours() : d.getHours()
let minute = d.getMinutes() < 10 ? '0' + d.getMinutes() : d.getMinutes()
let second = d.getSeconds() < 10 ? '0' + d.getSeconds() : d.getSeconds()
if (hasTime) {
return [year, month, day].join('-') + ' ' + [hour, minute, second].join(':')
} else {
return [year, month, day].join('-')
}
},
// 對話框關閉的回調
handleDialogClose () {
Object.assign(this.$data.channelForm, this.$options.data().channelForm)
this.dialogTitle = '新增頻道數據'
this.imgList = []
this.coverImgList = []
this.isEdit = false
},
openAddSource () {
this.dialogAddMediaVisible = true
},
openUpdateSource (item) {
// 初始化表單
this.channelForm.id = item.id
this.channelForm.title = item.title
this.channelForm.description = item.description
this.channelForm.coverUrls = item.coverUrls
this.channelForm.linkUrl = item.linkUrl
this.channelForm.type = item.type
this.channelForm.uploader = item.uploader
this.channelForm.source = item.source
this.channelForm.status = item.status
// 填充預覽圖片list
this.imgList = []
this.coverImgList = this.channelForm.coverUrls.split(',')
this.coverImgList.forEach((item, index) => {
this.imgList.push(
{
name: index.toString(),
url: item,
response: {
body: item
}
}
)
})
// 更換接口地址
this.isEdit = true
// 更改對話框標題
this.dialogTitle = '更改頻道數據'
this.dialogAddMediaVisible = true
},
updateSource () {
requestUpdateSource(this.$qs.stringify(this.channelForm)).then(data => {
if (data.status === 200) {
this.$notify.success({
title: '成功',
message: '更新頻道數據成功'
})
this.dialogAddMediaVisible = false
this.getSourceList()
} else {
this.$notify.error({
title: '失敗',
message: '更新頻道數據失敗'
})
}
})
},
onSubmit () {
this.$refs['channelForm'].validate((valid) => {
if (valid) {
if (this.isEdit) {
this.updateSource()
} else {
requestAddSource(this.$qs.stringify(this.channelForm)).then(data => {
if (data.status === 200) {
this.$notify.success({
title: '成功',
message: '新增頻道資源成功'
})
this.dialogAddMediaVisible = false
this.getSourceList()
// this.resetForm('BaseDataForm')
} else {
this.$notify.error({
title: '失敗',
message: '新增頻道資源失敗'
})
}
})
}
} else {
this.$notify.error({
title: '失敗',
message: '表單未填充完成'
})
return false
}
})
},
// 深度監聽中包含了這部分的邏輯
/* handleCurrentChange () {
this.getSourceList()
}, */
getSourceList () {
requestSourceList({
params: this.channelSearchForm
}).then(data => {
if (data.status === 200) {
this.tableData = data.body.data
this.pageTotal = data.body.total
} else {
this.$notify.error({
title: '失敗',
message: '查詢頻道數據失敗'
})
}
})
},
updateSourceStatus (id, status) {
requestUpdateSourceStatus(this.$qs.stringify({id: id, status: status})).then(data => {
if (data.status === 200) {
this.$notify.success({
title: '成功',
message: '審覈頻道成功'
})
this.getSourceList()
} else {
this.$notify.error({
title: '失敗',
message: '審覈頻道失敗'
})
}
})
},
deleteSource (id) {
this.$confirm('此操作將永久刪除該條頻道, 是否繼續?', '提示', {
confirmButtonText: '確定',
cancelButtonText: '取消',
type: 'error'
}).then(() => {
requestDeleteSource(this.$qs.stringify({id: id})).then(data => {
if (data.status === 200) {
this.$notify.success({
title: '成功',
message: '刪除頻道數據成功'
})
this.getSourceList()
} else {
this.$notify.error({
title: '失敗',
message: '刪除頻道數據失敗'
})
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消刪除'
})
})
}
}
}
</script>
<style scoped>
.program-list{
padding: 0 0 0 20px;
height: 70vh;
overflow: auto;
}
/*.program-list::-webkit-scrollbar {
width: 0 !important
}
.program-list {
!*隱藏滾動條,當IE下溢出,仍然可以滾動*!
-ms-overflow-style: none;
!*火狐下隱藏滾動條*!
scrollbar-width: none;
}*/
</style>