项目中上传图片使用的图片素材库组件

在components文件中新建一个子组件,文件的所有代码如下:在这里插入图片描述

<template>
  <div v-if="type == 'image'">
    <!--图片列表,value是完整url数组-->
    <ul class="el-upload-list el-upload-list--picture-card" v-for="(item,index) in value" :key="index">
      <li tabindex="0" class="el-upload-list__item is-ready" :style="'width: '+width+'px;height: '+height+'px'">
        <div>
          <img :src="item" alt="" class="el-upload-list__item-thumbnail">
          <span class="el-upload-list__item-actions">
            <!--向左排序-->
            <span class="el-upload-list__item-preview" v-if="index != 0" @click="moveMaterial(index,'up')">
              <i class="el-icon-back"></i>
            </span>
            <!--查看大图-->
            <span class="el-upload-list__item-preview" @click="zoomMaterial(index)">
              <i class="el-icon-view"></i>
            </span>
            <!--删除-->
            <span class="el-upload-list__item-delete" @click="deleteMaterial(index)">
              <i class="el-icon-delete"></i>
            </span>
            <!--向后排序-->
            <span class="el-upload-list__item-preview" v-if="index != value.length-1" @click="moveMaterial(index,'down')">
              <i class="el-icon-right"></i>
            </span>
          </span>
        </div>
      </li>
    </ul>
    <!--上传图片的+按钮显示与否,数量够即不显示-->
    <div tabindex="0" v-if="num > value.length" @click="toSeleteMaterial" class="el-upload el-upload--picture-card" :style="'width: '+width+'px;height: '+height+'px;'+'line-height:'+height+'px;'">
      <i class="el-icon-plus"></i>
    </div>

    <!--点击查看大图的弹窗-->
    <el-dialog append-to-body :visible.sync="dialogVisible" width="35%">
      <img :src="url" alt="" style="width: 100%">
    </el-dialog>

    <!--图片素材库弹窗-->
    <el-dialog :title="$t('rf_material.picLibrary')" append-to-body :visible.sync="listDialogVisible" width="70%">
      <el-container>
        <!--左侧分组-->
        <el-aside width="unset">
          <!--添加分组-->
          <div style="margin-bottom: 10px">
            <el-button class="el-icon-plus" size="small" @click="materialgroupAdd()">{{$t('rf_material.addGroup')}}</el-button>
          </div>
          <!--标签页-->
          <el-tabs tab-position="left" v-model="materialgroupObjId" v-loading="materialgroupLoading" @tab-click="tabClick">
            <el-tab-pane v-for="(item,index) in materialgroupList" :key="index" :name="item.id">
              <span slot="label"> {{item.name}}</span>
            </el-tab-pane>
          </el-tabs>
        </el-aside>
        <!--右侧卡片-->
        <el-main>
          <el-card>
            <!--卡片标题-->
            <div slot="header">
              <el-row>
                <el-col :span="12">
                  <span>{{materialgroupObj.name}}</span>
                  <!--id=-1即全部分组,不是全部分组方显示重命名和删除按钮-->
                  <span v-if="materialgroupObj.id != '-1'">
                    <el-button size="small" type="text" @click="materialgroupEdit(materialgroupObj)" class="el-icon-edit" style="margin-left: 10px;">{{$t('rfbutton.rename')}}</el-button>
                    <el-button size="small" type="text" @click="materialgroupDelete(materialgroupObj)" class="el-icon-delete" style="margin-left: 10px;color: red">{{$t('rfbutton.delete')}}</el-button>
                  </span>
                </el-col>
                <el-col :span="12" v-if="materialgroupObj.id != '-1'" style="text-align: right;">
                  <el-upload
                    :headers="headers"
                    action="/admin/sys-file/upload"
                    :file-list="[]"
                    :on-progress="handleProgress"
                    :before-upload="beforeUpload"
                    :on-success="handleSuccess">
                    <el-button size="small" type="primary">{{$t('rfbutton.uploadImg')}}</el-button>
                  </el-upload>
                </el-col>
              </el-row>
            </div>
            <!--卡片内容-->
            <div v-loading="tableLoading">
              <el-alert v-if="tableData.length <= 0" title="暂无数据" type="info" :closable="false" center show-icon></el-alert>
              <el-row :gutter="5"><!--gutter:栅格间隔-->
                <el-checkbox-group v-model="urls" :max="num - value.length">
                  <el-col :span="4" v-for="(item,index) in tableData" :key="index">
                  <el-card :body-style="{ padding: '5px' }">
                    <!--fit:确定图片如何适应容器框fill / contain / cover / none / scale-down;preview-src-list:开启图片预览功能-->
                    <el-image :src="item.url" fit="contain" :preview-src-list="[item.url]" style="width: 100%;height: 100px"></el-image>
                    <div>
                      <el-checkbox class="material-name" :label="item.url">{{$t('radio.choose')}}</el-checkbox>
                      <el-row>
                        <el-col :span="24" class="col-do">
                          <el-button type="text" size="medium"  @click="materialDel(item)">{{$t('rfbutton.delete')}}</el-button>
                        </el-col>
                      </el-row>
                    </div>
                  </el-card>
                </el-col>
                </el-checkbox-group>
              </el-row>
              <el-pagination
                      @size-change="sizeChange"
                      @current-change="pageChange"
                      :current-page.sync="page.currentPage"
                      :page-sizes="[12, 24]"
                      :page-size="page.pageSize"
                      layout="total, sizes, prev, pager, next, jumper"
                      :total="page.total"
                      class="pagination">
              </el-pagination>
            </div>
          </el-card>
        </el-main>
      </el-container>
      <span slot="footer" class="dialog-footer">
        <el-button @click="listDialogVisible = false">{{$t("cancelText")}}</el-button>
        <el-button type="primary" @click="submitUrls">{{$t("submitText")}}</el-button>
      </span>
    </el-dialog>
  </div>

</template>

<script>
  import { getFileService,getGrouplist,addGroupObj,putGroupObj,delGroupObj,getPicLibraryList,addPicLibraryObj,delPicLibraryObj } from '@/util/util'
  import store from '@/store'
  import { mapGetters } from 'vuex'

  export default {
    name: "materialList",
    props: {
      //素材数据
      value:{
        type: Array,
        default() {
          return []
        },
      },
      //素材类型
      type:{
        type: String,
      },
      //素材限制数量,默认5个
      num:{
        type: Number,
        default() {
          return 5
        },
      },
      //宽度
      width: {
        type: Number,
        default() {
          return 150
        }
      },
      //高度
      height: {
        type: Number,
        default() {
          return 150
        }
      }
    },
    data() {
      return {
        headers: {
          Authorization: 'Bearer ' + store.getters.access_token
        },
        dialogVisible: false,
        url: '',
        listDialogVisible: false,
        materialgroupList: [],
        materialgroupObjId: '',
        materialgroupObj: {},
        materialgroupLoading: false,
        tableData: [],
        page: {
          total: 0, // 总页数
          currentPage: 1, // 当前页数
          pageSize: 12, // 每页显示多少条
          ascs: [],//升序字段
          descs: 'create_time'//降序字段
        },
        tableLoading: false,
        groupId: null,
        urls: [],
        baseImgUrl: '',
      }
    },
    computed: {
      ...mapGetters(['permissions','languageID','language'])
    },
    created:function () {
      //在页面创建时需处理内容,在此添加,比如给下拉框绑定change事件等
      this.baseImgUrl=getFileService()
    },
    methods:{
      //向左右排序
      moveMaterial(index,type){
        if(type == 'up'){//向左
          let tempOption = this.value[index - 1]
          this.$set(this.value, index - 1, this.value[index])
          this.$set(this.value, index, tempOption)
        }
        if(type == 'down'){//向右
          let tempOption = this.value[index + 1]
          this.$set(this.value, index + 1, this.value[index])
          this.$set(this.value, index, tempOption)
        }
      },
      //查看大图
      zoomMaterial(index){
        this.dialogVisible = true
        this.url = this.value[index]
      },
      //删除图片
      deleteMaterial(index){
        let that = this
        this.$confirm('是否确认删除?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(function() {
          that.value.splice(index,1)
          that.urls = []
        })
      },
      //打开素材库
      toSeleteMaterial(){
        this.listDialogVisible = true
        if(this.tableData.length <= 0){
          this.materialgroupPage()
        }
      },
      //分组数据
      materialgroupPage(){
        this.materialgroupLoading = true
        getGrouplist(this.languageID).then(res => {
          this.materialgroupLoading = false
          this.materialgroupList=res.data.data
          this.materialgroupList.unshift({
            id: '-1',
            name: '全部分组'
          })
          this.tabClick({
            index: 0
          })
        });
      },
      //删除分组
      materialgroupDelete(materialgroupObj){
        let that = this
        this.$confirm('是否确认删除该分组?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(function() {
          delGroupObj(materialgroupObj.id)
            .then(function() {
              that.$delete(that.materialgroupList, materialgroupObj.index)
              that.getPage(that.page)
            })
        })
      },
      //重命名分组
      materialgroupEdit(materialgroupObj){
        let that = this
        this.$prompt('请输入分组名', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          inputValue: materialgroupObj.name,
        }).then(({ value }) => {
          materialgroupObj.name=value
          putGroupObj(materialgroupObj).then(function() {
            materialgroupObj.name = value
            that.$set(that.materialgroupList, materialgroupObj.index, materialgroupObj)
          })
        })
      },
      //添加分组
      materialgroupAdd(){
        let that = this
        //element的MessageBox消息弹窗
        this.$prompt('请输入分组名', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
        }).then(({ value }) => {
          addGroupObj({
            name: value,
            languageId:this.languageID
          }).then(function() {
            that.materialgroupPage()//刷新分组数据
          })
        })
      },
      //点击标签页事件
      tabClick(tab,event){
        console.log(tab, event);
        this.urls = []
        let index = Number(tab.index)
        let materialgroupObj = this.materialgroupList[index]
        materialgroupObj.index = index
        this.materialgroupObj = materialgroupObj
        this.materialgroupObjId = materialgroupObj.id
        this.page.currentPage = 1
        this.page.total = 0
        if(materialgroupObj.id != '-1'){
          this.groupId = materialgroupObj.id
        }else{
          this.groupId = null
        }
        this.getPage(this.page)
      },
      getPage(page, params) {
        this.tableLoading = true
        getPicLibraryList(Object.assign({
          current: this.page.currentPage,
          size: this.page.pageSize,
          groupId: this.groupId,
          languageId: this.languageID
        })).then(res=>{
          this.tableLoading = false
          this.tableData = res.data.data.records
          this.page.total = res.data.data.total
          this.page.currentPage = res.data.data.current
          this.page.pageSize = res.data.data.size
        }).catch(() => {
          this.tableLoading=false
        })
      },
      //当前每页总数改变时触发的函数
      sizeChange(val) {
        console.log(val)
        this.page.currentPage = 1
        this.page.pageSize = val
        this.getPage(this.page)
      },
      //当前页码改变时触发的函数,即你点击 1 , 2 , 3 ,它就跳到相应的数据页
      pageChange(val) {
        console.log(val)
        this.page.currentPage = val
        //this.page.pageSize = val
        this.getPage(this.page)
      },
      //删除图片
      materialDel(item){
        let that = this
        this.$confirm('是否确认删除该素材?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(function() {
          delPicLibraryObj(item.id)
            .then(function() {
              that.$message.success(that.$t("rfbutton.delete")+' '+that.$t("successText"))
              that.getPage(that.page)
            })
        })
      },
      handleProgress(event, file, fileList){
        // let uploadProgress = file.percentage.toFixed(0)
        // this.uploadProgress = uploadProgress
      },
      //上传图片格式和大小校验
      beforeUpload(file){
        const isPic =
          file.type === "image/jpeg" ||
          file.type === "image/png" ||
          file.type === "image/gif" ||
          file.type === "image/jpg"
        const isLt2M = file.size / 1024 / 1024 < 2
        if (!isPic) {
          this.$message.error("上传图片只能是 JPG、JPEG、PNG、GIF 格式!")
          return false
        }
        if (!isLt2M) {
          this.$message.error('上传图片大小不能超过 2MB!')
        }
        return isPic && isLt2M
      },
      //上传图片成功
      handleSuccess(res, file, fileList){
        // this.uploadProgress = 0
        console.log(res, file, fileList)
        let that = this
        addPicLibraryObj({
          type: 1,//1图片,2视频
          groupId: this.groupId != '-1' ? this.groupId : null,
          languageId: this.languageID,
          name: file.name,
          url: this.baseImgUrl+ res.data.bucketName + '/' + res.data.fileName
          // url: res.link
        }).then(function() {
          that.$message.success(that.$t("rfbutton.uploadImg")+' '+that.$t("successText"))
          that.getPage(that.page)
        })
      },
      //提交选取的图片
      submitUrls(){
        this.urls.forEach(item => {
          this.$set(this.value,this.value.length, item)
        })
        this.listDialogVisible=false
      },
      materialRename(item){
        let that = this
        this.$prompt('请输入素材名', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          inputValue: item.name,
        }).then(({ value }) => {
          putObj({
            id: item.id,
            name: value
          }).then(function() {
            that.getPage(that.page)
          })
        }).catch(() => {

        })
      },
      materialUrl(item){
        let that = this
        this.$prompt('素材链接', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          inputValue: item.url,
        }).then(({ value }) => {

        }).catch(() => {

        })
      },
      handleCommand(command) {
        let that = this
        let s = command.split('-')
        putObj({
          id: s[0],
          groupId: s[1]
        }).then(function() {
          that.getPage(that.page)
        })
      }
    }
  };
</script>

<style lang="scss" scoped>
  .material-name{
    padding: 8px 0px;
  }
  .col-do{
    text-align: center;
  }
  .button-do{
    padding: unset!important;
    font-size: 12px;
  }
</style>


文件中涉及的接口需换成自己后台的接口,即可直接使用。

<MaterialList v-model="imageArr" :value="imageArr" style="width: 500px" type="image" :num=1 :width=150 :height=150></MaterialList>


import MaterialList from '@/components/material'

components: {
          MaterialList
        },

效果如链接中管理闪屏商品-新增-商品图片
添加链接描述在这里插入图片描述

发布了55 篇原创文章 · 获赞 4 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44770377/article/details/104845921