vue form表单上传文件弹窗组件使用

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!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天下·第二

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值