vue form表单上传文件弹窗组件使用
先放图,后上码
创建组件createIdeaPop.vue
直接上代码啦
createIdeaPop.vue
<template>
<div class="modal-bg" v-show="showPop" @mousemove="modalMove" @mouseup="cancelMove">
<div class="modal-container">
<div class="modal-header" @mousedown="setStartingPoint">
{{ groupName }} => {{ typeName }}
</div>
<div class="modal-main">
<slot></slot>
<div class="form">
<div class="popTitle">Idea Title</div>
<div class="flex-row">
<el-input v-model="form.title" placeholder="Please describe your idea in one sentence"></el-input>
<!-- <type>{{ type || form.type }}</type>-->
</div>
<div class="popSubTitle">Background</div>
<div class="flex-row">
<el-input type="textarea" class="input-small" v-model="form.background" placeholder="We appreciate that you can share us with your exciting findings or thoughts."></el-input>
</div>
<upload v-model="form.background_files" ref="upload1">
<add></add>
</upload>
<div class="popSubTitle">Description</div>
<div class="flex-row">
<el-input v-model="form.description" type="textarea" placeholder="The technology/implementation method for your idea."></el-input>
</div>
<upload v-model="form.description_files" ref="upload1">
<add></add>
</upload>
<div class="popSubTitle">Benefits</div>
<div class="flex-row">
<el-input v-model="form.benefits" type="textarea" placeholder="Who are our customers, .What benefits it can bring to our customer."></el-input>
</div>
<upload v-model="form.benefits_files" ref="upload1">
<add></add>
</upload>
<div class="popSubTitle">Other</div>
<div class="flex-row">
<el-input v-model="form.others" type="textarea" placeholder="We appreciate that you can share us with your exciting findings or thoughts."></el-input>
</div>
<upload v-model="form.others_files" ref="upload1">
<add></add>
</upload>
<div class="popSubTitle">Attachments</div>
<div class="flex-row">
<el-input v-model="form.attachments" type="textarea" placeholder="We appreciate that you can share us with your exciting findings or thoughts."></el-input>
</div>
<upload v-model="form.attachments_files" ref="upload1">
<add></add>
</upload>
</div>
</div>
<div class="modal-footer">
<el-button round @click="hideModal">取消</el-button>
<el-button type="primary" round @click="submit">确认</el-button>
</div>
</div>
</div>
</template>
<script>
import upload from '@/components/upload/index'
import add from '@/components/add/index'
import {create_ideas} from "@/api/ideas";
const form = {
type: '',
title: '',
background: '',
background_files: [],
description: '',
description_files: [],
benefits: '',
benefits_files: [],
others: '',
others_files: [],
attachments: '',
attachments_files: []
}
export default {
name: 'createIdeaPop',
components:{
upload,
add
},
props: {
showPop: {
type: Boolean,
default: false
},
typeName: {
type: String,
default: ''
},
groupName: String,
groups: {
type: Array,
default: null
}
},
data() {
return {
id: this.$route.params.id,
title: 'tile',
form: { ...form },
x: 0,
y: 0,
node: null,
isCanMove: false,
confirmLoading: false,
}
},
mounted() {
this.node = document.querySelector('.modal-container')
},
methods: {
hideModal() {
this.$emit('hideModal')
},
submit() {
this.$emit('submit')
console.log(this.form)
var title = this.form.title
var background = this.form.background
var description = this.form.description
var benefits = this.form.benefits
if (title === '' || background === '' || description === '' || benefits === '') {
// alert('11111111')
return this.$toast('please fill in the blanks');
}
this.form.type = this.typeName
this.loading = true
var data = JSON.parse(JSON.stringify({...this.form}))
// 将文件的格式转换成id
Object.keys(data).forEach(key => {
if (key.includes('_files')) {
data[key] = data[key].map(file => file.response.id)
console.log(data[key])
}
})
console.log(data)
create_ideas(data).then(() => {
// console.log(res)
this.loading = false
this.form = { ...form }
this.$router.push('/success')
}).catch(()=>{
// console.log(err)
})
// this.$router.push('/success')
},
setStartingPoint(e) {
this.x = e.clientX - this.node.offsetLeft
this.y = e.clientY - this.node.offsetTop
this.isCanMove = true
},
modalMove(e) {
if (this.isCanMove) {
this.node.style.left = e.clientX - this.x + 'px'
this.node.style.top = e.clientY - this.y + 'px'
}
},
cancelMove() {
this.isCanMove = false
}
}
}
</script>
<style scoped lang="stylus">
.modal-bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, .5);
z-index: 10;
}
.modal-container {
//width: 50%;
//height: 70%;
width: 700px;
height: 670px;
background: #fff;
border-radius: 10px;
overflow: auto;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.modal-header {
height: 7%;
font-size: var(--font-size-large);
font-weight: bold;
background: #409EFF;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
cursor: move;
}
.modal-footer {
height 7%
display: flex;
align-items: center;
justify-content: center;
/*height: 67px;*/
border-top: 1px solid #ddd;
}
.modal-footer button {
width: 100px;
}
.modal-main {
display flex-shrink
height 86%
padding: 15px 40px;
margin-right 20px
}
.popTitle
font-weight bold
font-size large
padding 7px 0 7px 0
/*margin-right 5px*/
.popSubTitle
font-weight bold
font-size min-inline-size
padding 7px 0 7px 0
</style>
添加上传和添加图标组件
1.uploud/index.vue
<template>
<el-upload class="upload" ref="upload" :on-change="setIcon" :accept="accept" :file-list="fileList" :action="action" :headers="headers" :on-success="onSuccess" :on-remove="handleRemove" :before-remove="beforeRemove" multiple>
<slot></slot>
</el-upload>
</template>
<script>
import { getToken } from '@/api/request'
import { getFileType } from '@/utils'
export default {
model: {
prop: 'fileList',
event: 'updateFileList'
},
props: {
fileList: Array
},
data() {
return {
action: process.env.VUE_APP_BASE_URL + '/api/files',
headers: { Authorization: getToken() },
accept:
'image/png, image/jpeg, video/mp4, application/pdf, .doc, .docx, .xls, .xlsx, .ppt, .pptx'
}
},
created() {},
methods: {
setIcon(file, fileList) {
if (file.status !== 'ready') return
const index = fileList.findIndex(item => item === file)
const fileType = getFileType(file.name)
this.$nextTick(() => {
this.$refs.upload.$el.querySelectorAll('a.el-upload-list__item-name')[
index
].innerHTML = `<img class="file-icon" src="/imgs/${fileType.toLowerCase()}.svg" alt="file-icon">${
file.name
}`
})
},
handleRemove(file, fileList) {
this.updateFileIds(fileList)
},
beforeRemove(file) {
return this.$confirm(`Are you sure to delete ${file.name}?`, 'Tips', {
cancelButtonText: 'Cancel',
confirmButtonText: 'OK'
})
},
onSuccess(response, file, fileList) {
this.updateFileIds(fileList)
},
updateFileIds(fileList) {
// const fileIds = fileList.map(file => file.response.id)
this.$emit('updateFileList', fileList)
},
clear() {
this.$refs.upload.clearFiles()
this.updateFileIds([])
}
},
watch: {
value(val) {
console.log(val)
}
}
}
</script>
<style scoped lang="stylus">
.upload
width 340px
& >>>
.el-upload-list__item-name
padding-left 0
.el-upload-list__item:first-child
margin-top 8px
.el-upload-list__item
margin-top 4px
.file-icon
width 14px
height 14px
margin-right: 8px;
display: inline-block;
vertical-align: top;
margin-top: 6px;
</style>
2.add/index.vue组件
<template>
<div class="add flex">
<img src="@/assets/plus.svg">Add picture/video</div>
</template>
<style scoped lang="stylus">
.add
color #6063FF
font-size var(--font-size-small)
font-weight bold
cursor pointer
img
margin-right 6px
</style>
done!