用element-ui组件和后端接口完成图片上传(SMPE框架)

图片上传

全部代码:

<template>
<el-upload
          ref="up"
          :file-list="form.resourceList"
          :show-file-list="true"
          action="/api/resource/uploadImage"
          list-type="picture-card"
          :auto-upload="true"
          :limit="9"
          :on-exceed="handleExceed"
          :http-request="handleFileSuccess"
        >
          <i slot="default" class="el-icon-plus" />
          <!-- :src="baseApi+'/api/resource/uploadImage'+file.path" -->
          <div slot="file" slot-scope="{ file }">
            <img
              class="el-upload-list__item-thumbnail"
              :src="file.path"
              alt=""
            />
            <span class="el-upload-list__item-actions">
              <!-- 预览 -->
              <span
                class="el-upload-list__item-preview"
                @click="handlePictureCardPreview(file)"
              >
                <i class="el-icon-zoom-in" />
              </span>
              <!-- 替换 -->
              <span
                class="el-upload-list__item-preview"
                @click="handleChange(file)"
              >
                <i class="el-icon-edit" />
              </span>
              <!-- 删除 -->
              <span
                v-if="!disabled"
                class="el-upload-list__item-delete"
                @click="handleRemove(file)"
              >
                <i class="el-icon-delete" />
              </span>
            </span>
          </div>
        </el-upload>
        <!-- 预览-->
        <el-dialog :visible.sync="dialogVisible">
          <img width="100%" :src="dialogImageUrl" alt="" />
        </el-dialog>
</template>
<script>
import { form } from "@crud/crud"
import { upload } from "@/utils/upload.js"
import CRUD from "@crud/crud"
const defaultForm = {
  resourceList: [],
  deleteIds: [],
}
cruds() {
    return CRUD({
      title: "商品",
      url: "api/goods",
      query: { enabled: "true" },
    })
 },
export default {
  mixins: [form(defaultForm)],
  data() {
    return {
      dialogImageUrl: "",
      dialogVisible: false,
      disabled: false,
    };
  },
  computed: {
    ...mapGetters(["baseApi"]),//端口号
  },
  methods: {
    // 删除图片
    handleRemove(file) {
      // console.log(file,"file")
      this.form.deleteIds.push(file.id);
      for (let i = 0; i < this.form.resourceList.length; i++) {
        if (this.form.resourceList[i].id === file.id) {
          // splice(索引,length)删除指定id的数据
          this.form.resourceList.splice(i, 1);
        }
      }
    },
    // 改变图片
    handleChange(file) {
      console.log(file, "file");
      this.$confirm("此操作将用新图片替代该图片, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          // 先删除图片
          let index = 0
          this.form.deleteIds.push(file.id);
          for (let i = 0; i < this.form.resourceList.length; i++) {
            if (this.form.resourceList[i].id === file.id) {
              // splice(索引,length,代替内容)替代指定id的数据
              this.form.resourceList.splice(i, 1)
              index = i
            }
          }
          // 再选择新的图
          this.$refs["up"].$refs["upload-inner"].handleClick(); //出现上传图片界面
          upload("/api/resource/uploadImage", file)
            .then((res) => {
              // 新图片替代旧图片
              this.form.resourceList.splice(index,1,res.data.data)
            })
            .catch((err) => {
              console.log("返回错误", err);
            });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消编辑图片",
          });
        });
    },
    // 预览
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url
      this.dialogVisible = true
    },
    // 文件个数超出指定个数
    handleExceed(files, fileList) {
      this.$message.warning(
        `当前限制选择 9 个图片,本次选择了 ${files.length} 个图片,共选择了 ${
          files.length + fileList.length
        } 个图片`
      )
    },
    //上传图片
    handleFileSuccess(file) {
      upload("/api/resource/uploadImage", file.file)
        .then((res) => {
          this.form.resourceList.push(res.data.data)
        })
        .catch((err) => {
          console.log("返回错误", err)
        })
    },

   
  },
}
</script>



一、组件部分

上传(element-ui)

1、代码
 <el-upload
          ref="up"
          :file-list="form.resourceList"
          :show-file-list="true"
          action="/api/resource/uploadImage"
          list-type="picture-card"
          :auto-upload="true"
          :limit="9"
          :on-exceed="handleExceed"
          :http-request="handleFileSuccess"
        >
          <i slot="default" class="el-icon-plus" />
          <div slot="file" slot-scope="{ file }">
            <img
              class="el-upload-list__item-thumbnail"
           :src="baseApi+'/api/resource/uploadImage'+file.path""
              alt=""
            />
            <span class="el-upload-list__item-actions">
              <!-- 预览 -->
              <span
                class="el-upload-list__item-preview"
                @click="handlePictureCardPreview(file)"
              >
                <i class="el-icon-zoom-in" />
              </span>
              <!-- 替换 -->
              <span
                class="el-upload-list__item-preview"
                @click="handleChange(file)"
              >
                <i class="el-icon-edit" />
              </span>
              <!-- 删除 -->
              <span
                v-if="!disabled"
                class="el-upload-list__item-delete"
                @click="handleRemove(file)"
              >
                <i class="el-icon-delete" />
              </span>
            </span>
          </div>
        </el-upload>
        <!--预览 -->
         <el-dialog :visible.sync="dialogVisible">
          <img width="100%" :src="dialogImageUrl" alt="" />
        </el-dialog>
2、讲解

(1)、el-upload属性介绍

  1. file-list

(1)上传的文件列表
(2)一般是接口获取的属性和返回给后端的参数(如form.resourceList)

  1. show-file-list

(1)是否显示已上传文件列表
(2)boolean类型(true or false)

  1. active

(1)必选参数,上传的地址
(2)比如代码中的 /api/resource/uploadImage 就是后端上传图片的接口

  1. list-type

(1)文件列表的类型
(2)string类型(text/picture/picture-card)

  1. auto-upload

(1)是否在选取文件后立即进行上传
(2)true false

  1. limit

(1)最大允许上传个数
(2)number类型

  1. on-exceed

(1)文件超出个数限制时的钩子
(2)function(files, fileList)

  1. http-request

(1)覆盖默认的上传行为,可以自定义上传的实现
(2)function

  1. limit

(1)最大允许上传个数
(2)number类型
(2)图片

  1. img的src

(1)baseApi+’/api/resource/uploadImage’+file.path
(2)baseApi是端口号,/api/resource/uploadImage是接口地址,file.path是接口传来的参数路径

  1. 预览、修改、删除

(1)点击事件触发方法

二、前后端交互、传递数据

方法全部代码
methods: {
    // 删除图片
    handleRemove(file) {
      // console.log(file,"file")
      this.form.deleteIds.push(file.id);
      for (let i = 0; i < this.form.resourceList.length; i++) {
        if (this.form.resourceList[i].id === file.id) {
          // splice(索引,length)删除指定id的数据
          this.form.resourceList.splice(i, 1);
        }
      }
    },
    // 改变图片
    handleChange(file) {
      console.log(file, "file");
      this.$confirm("此操作将用新图片替代该图片, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          // 先删除图片
          let index = 0;
          this.form.deleteIds.push(file.id);
          for (let i = 0; i < this.form.resourceList.length; i++) {
            if (this.form.resourceList[i].id === file.id) {
              // splice(索引,length,代替内容)替代指定id的数据
              this.form.resourceList.splice(i, 1)
              index = i
            }
          }
          // 再选择新的图
          this.$refs["up"].$refs["upload-inner"].handleClick(); //出现上传图片界面
          upload("/api/resource/uploadImage", file)
            .then((res) => {
              // 新图片替代旧图片
              this.form.resourceList.splice(index,1,res.data.data)
            })
            .catch((err) => {
              console.log("返回错误", err);
            });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消编辑图片",
          });
        });
    },
    // 预览
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    // 文件个数超出指定个数
    handleExceed(files, fileList) {
      this.$message.warning(
        `当前限制选择 9 个图片,本次选择了 ${files.length} 个图片,共选择了 ${
          files.length + fileList.length
        } 个图片`
      );
    },
    //上传图片
    handleFileSuccess(file) {
      upload("/api/resource/uploadImage", file.file)
        .then((res) => {
          this.form.resourceList.push(res.data.data);
        })
        .catch((err) => {
          console.log("返回错误", err);
        });
    },

框架里的一个upload方法

import axios from 'axios'
import { getToken } from '@/utils/auth'

export function upload(api, file) {
  var data = new FormData()
  data.append('file', file)
  const config = {
    headers: { 'Authorization': getToken() }
  }
  return axios.post(api, data, config)
}
1、上传图片
(1)代码
handleFileSuccess(file) {
      upload("/api/resource/uploadImage", file.file)
        .then((res) => {
          this.form.resourceList.push(res.data.data);
        })
        .catch((err) => {
          console.log("返回错误", err);
        });
    },
(2)解释
  1. res.data.data是需要返回后端的一个对象,里面包含了上传图片的type\name\path
  2. 将res.data.data加入到this.form.resourceList数组里
  3. push()是将元素加入到数组的最后面
2、删除图片
(1)代码
handleRemove(file) {
      // console.log(file,"file")
      this.form.deleteIds.push(file.id);
      for (let i = 0; i < this.form.resourceList.length; i++) {
        if (this.form.resourceList[i].id === file.id) {
          // splice(位置,length)删除指定id的数据
          this.form.resourceList.splice(i, 1);
        }
      }
    },
(2)解释
  1. 把删除的图片的id放到一个数组里(this.form.deleteIds)返回给后端,方便删除数据库里的数据
  2. 通过for循环进行判断是哪一个id
  3. 把返回给后端的图片列表参数(this.form.resourceList)中的对应id位置的删除那条数据
3、修改图片
(1)代码
handleChange(file) {
      console.log(file, "file");
      this.$confirm("此操作将用新图片替代该图片, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          // 先删除图片
          let index = 0;
          this.form.deleteIds.push(file.id);
          for (let i = 0; i < this.form.resourceList.length; i++) {
            if (this.form.resourceList[i].id === file.id) {
              // splice(索引,length,代替内容)替代指定id的数据
              this.form.resourceList.splice(i, 1)
              index = i
            }
          }
          // 再选择新的图片
          this.$refs["up"].$refs["upload-inner"].handleClick(); //出现上传图片界面
          upload("/api/resource/uploadImage", file)
            .then((res) => {
              // 新图片替代旧图片
              this.form.resourceList.splice(index,1,res.data.data)
            })
            .catch((err) => {
              console.log("返回错误", err)
            })
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消编辑图片",
          })
        })
    },
(2)解释

1.修改图片采用的是先删除后上传的方法,但是需要进行提示,否则一旦点击编辑就删除了图片,用户体验感差。

  1. index变量是为了记录旧图片在数组中所在的位置,便于后面上传新图片时可以插到相应位置。
  2. this.$refs["up"].$refs["upload-inner"].handleClick(); 点击后出现上传界面,进行选择图片。( this.$refs.(ref值).方法()可以使用组件的所有方法)
  3. this.form.resourceList.splice(index,1,res.data.data) 新图片替代旧图片
  4. splice(index,length,[item]) 进行删除、替换、添加元素

(1)第一个参数是在哪个地方插入元素
(2)第二个参数传入你要删除几个元素
(3)第三个元素是用于替换前面的元素
(4)传递一个参数时 : 传递一个参数的时候表示从这个参数的位置开始一直截取到最后
(5)传递两个参数,第一个参数表示开始的位置,第二个参数表示要截取的个数;如果第二个参数为0,则表示不截取,返回的空数组,原来的数组不变
(6)传递三个参数的时候:如果第二个参数是0,则是在index处添加item;如果第二个参数不为0,则是从index处删除length个项,然后添加item
(7)总结:删除:splice(index,length);添加splice(index,0,item);替换 splice(index,1,item)

4、预览图片
(1)代码
// 预览图片
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url
      this.dialogVisible = true
    }
5、限定图片个数
(1)代码
 // 文件个数超出指定个数
    handleExceed(files, fileList) {
      this.$message.warning(
        `当前限制选择 9 个图片,本次选择了 ${files.length} 个图片,共选择了 ${
          files.length + fileList.length
        } 个图片`
      )
    },

当图片个数超过限制时会提醒文字

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值