12.Vue2 如何使用 Element 组件实现图片上传功能

书诚小驿2024/12/04前端知识库Vue3

一、安装 Element 官网组件 Upload

官网链接:Element 官网组件open in new window

  1. npm安装element-ui
npm i element-ui -S
  1. 引入 Element,main.js完整引入
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import ElementUI from "element-ui";
import "element-ui/lib/theme-chalk/index.css";
Vue.config.productionTip = false;
Vue.use(ElementUI);
new Vue({
  router,
  store,
  render: (h) => h(App),
}).$mount("#app");
  1. HomeView.vue引入el-upload组件
<template>
  <div>
    <el-upload
      class="upload-demo"
      action="https://jsonplaceholder.typicode.com/posts/"
      :file-list="fileList"
    >
      <el-button size="small" type="primary">点击上传</el-button>
      <div slot="tip" class="el-upload__tip">上传文件的类型和大小限制提示</div>
    </el-upload>
  </div>
</template>
<script>
export default {
  data() {
    return {
      fileList: [],
    };
  },
};
</script>
<style lang="scss"></style>

二、使用 Element Upload 组件上传图片

1. 上传文件列表

  1. action="http://xxx" 将文件上传到实际的服务器接口地址
<el-upload
  class="upload-demo"
  action="https://jsonplaceholder.typicode.com/posts/"
>
</el-upload>
  1. drag 是否启用拖拽上传
<el-upload
  class="upload-demo"
  action="https://jsonplaceholder.typicode.com/posts/"
  drag
>
</el-upload>
  1. :file-list="fileList"用于存储已上传的文件列表
<template>
  <div>
    <el-upload
      class="upload-demo"
      action="https://jsonplaceholder.typicode.com/posts/"
      :file-list="fileList"
    >
      <el-button size="small" type="primary">点击上传</el-button>
      <div slot="tip" class="el-upload__tip">上传文件的类型和大小限制提示</div>
    </el-upload>
  </div>
</template>
<script>
export default {
  data() {
    return {
      fileList: [],
    };
  },
};
</script>
<style lang="scss"></style>
  1. :on-preview="handlePreview"上传文件列表中点击文件链接或预览图标时的回调函数

  2. :before-remove="beforeRemove" 移除文件之前的钩子函数

  3. :on-remove"handleRemove" 文件列表中移除文件时的回调函数

  4. :on-exceed="handleExceed" 当文件超出限制时的回调函数

  5. :limit="3" 限制上传文件的数量

  6. multiple 允许同时选择多个文件

  7. :on-success="handleAvatarSuccess" 文件上传成功时的回调函数

  8. :before-upload="beforeAvatarUpload" 限制用户上传的图片格式和大小。

<template>
  <div>
    <el-upload
      class="upload-demo"
      action="https://jsonplaceholder.typicode.com/posts/"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :before-remove="beforeRemove"
      multiple
      :limit="3"
      :on-exceed="handleExceed"
      :file-list="fileList"
      :before-upload="beforeAvatarUpload"
      :on-success="handleAvatarSuccess"
    >
      <el-button size="small" type="primary">点击上传</el-button>
      <div slot="tip" class="el-upload__tip">
        只能上传jpg/png文件,且不超过500kb
      </div>
    </el-upload>
  </div>
</template>
<script>
export default {
  data() {
    return {
      fileList: [],
    };
  },
  methods: {
    handleRemove(file, fileList) {
      console.log(file, fileList);
    },
    handlePreview(file) {
      console.log(file);
    },
    handleExceed(files, fileList) {
      this.$message.warning(
        `当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${
          files.length + fileList.length
        } 个文件`
      );
    },
    handleAvatarSuccess(res, file) {
      // URL.createObjectURL() 生成的 URL 是临时的,可以在浏览器中直接使用
      console.log(res, URL.createObjectURL(file.raw));
    },
    beforeRemove(file, fileList) {
      console.log(fileList);
      return this.$confirm(`确定移除 ${file.name}`);
    },
    beforeAvatarUpload(file) {
      const isJPG = file.type === "image/jpeg";
      const isLt2M = file.size / 1024 / 1024 < 2;

      if (!isJPG) {
        this.$message.error("上传头像图片只能是 JPG/JPEG 格式!");
      }
      if (!isLt2M) {
        this.$message.error("上传头像图片大小不能超过 2MB!");
      }
      return isJPG && isLt2M;
    },
  },
};
</script>
<style lang="scss"></style>

2. 上传回显图片

  1. :show-file-list="false" 不显示文件列表
<template>
  <div>
    <el-upload
      class="upload-demo"
      action="https://jsonplaceholder.typicode.com/posts/"
      :file-list="fileList"
      :show-file-list="false"
    >
      <el-button size="small" type="primary">点击上传</el-button>
      <div slot="tip" class="el-upload__tip">上传文件的类型和大小限制提示</div>
    </el-upload>
  </div>
</template>
<script>
export default {
  data() {
    return {
      fileList: [],
    };
  },
};
</script>
<style lang="scss"></style>
  1. :show-file-list="false":before-upload="beforeAvatarUpload"结合使用,可以退隐藏列表,然后回显图片
<template>
  <div>
    <el-upload
      class="avatar-uploader"
      action="https://jsonplaceholder.typicode.com/posts/"
      :show-file-list="false"
      :on-success="handleAvatarSuccess"
    >
      <img v-if="imageUrl" :src="imageUrl" class="avatar" />
      <i v-else class="el-icon-plus"></i>
    </el-upload>
  </div>
</template>
<script>
export default {
  data() {
    return {
      imageUrl: "",
    };
  },
  methods: {
    handleAvatarSuccess(res, file) {
      console.log(res);
      this.imageUrl = URL.createObjectURL(file.raw);
    },
  },
};
</script>
<style scoped>
.avatar-uploader {
  width: 150px;
  height: 150px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  cursor: pointer;
  border: 1px solid #8c939d;
}
.el-icon-plus {
  font-size: 28px;
  width: 150px;
  height: 150px;
  line-height: 150px;
  padding-top: 60px;
  box-sizing: border-box;
}
.avatar {
  width: 150px;
  height: 150px;
  display: block;
}
</style>
  1. list-type="picture-card"指定文件列表的外观类型。
  • file:默认的文件列表样式
  • picture::这种样式适用于图片文件,会以缩略图的形式展示图片文件列表
  • picture-card:图片列表样式,适合用于图片墙或照片墙的布局

使用了list-type="picture-card"相当于是:show-file-list="false":before-upload="beforeAvatarUpload"结合使用,可以退隐藏列表,然后回显图片

<template>
  <el-upload
    action="https://jsonplaceholder.typicode.com/posts/"
    list-type="picture-card"
    :on-preview="handlePictureCardPreview"
    :on-remove="handleRemove"
  >
    <i class="el-icon-plus"></i>
  </el-upload>
  <el-dialog :visible.sync="dialogVisible">
    <img width="100%" :src="dialogImageUrl" alt="" />
  </el-dialog>
</template>
<script>
export default {
  data() {
    return {
      dialogImageUrl: "",
      dialogVisible: false,
    };
  },
  methods: {
    handleRemove(file, fileList) {
      console.log(file, fileList);
    },
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
  },
};
</script>
  1. 使用 slot-scope="{ file }"去设置缩略图模版。
<template>
  <div>
    <el-upload action="#" list-type="picture-card" :auto-upload="false">
      <i slot="default" class="el-icon-plus"></i>
      <!-- 缩略图模版 -->
      <div slot="file" slot-scope="{ file }">
        <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
        <span class="el-upload-list__item-actions">
          <span
            class="el-upload-list__item-preview"
            @click="handlePictureCardPreview(file)"
          >
            <i class="el-icon-zoom-in"></i>
          </span>
          <span
            v-if="!disabled"
            class="el-upload-list__item-delete"
            @click="handleDownload(file)"
          >
            <i class="el-icon-download"></i>
          </span>
          <span
            v-if="!disabled"
            class="el-upload-list__item-delete"
            @click="handleRemove(file)"
          >
            <i class="el-icon-delete"></i>
          </span>
        </span>
      </div>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="dialogImageUrl" alt="" />
    </el-dialog>
  </div>
</template>
<script>
export default {
  data() {
    return {
      dialogImageUrl: "",
      dialogVisible: false,
      disabled: false,
    };
  },
  methods: {
    // 移除
    handleRemove(file) {
      console.log(file);
    },
    // 预览
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    // 下载
    handleDownload(file) {
      console.log(file);
    },
  },
};
</script>
  1. :on-change="handleChange"

绑定一个事件处理函数,该函数会在文件上传状态发生变化时被触发。具体来说,这个事件会在文件选中、上传成功、上传失败或文件被移除时触发。这个方法通常会接收三个参数

  • file:当前操作的文件对象。
  • fileList:当前的文件列表数组。
  • event:原生的事件对象(如果是从 元素选择文件触发的上传,这个参数会存在)。
<template>
  <div>
    <el-upload
      class="upload-demo"
      action="https://jsonplaceholder.typicode.com/posts/"
      :on-change="handleChange"
      :file-list="fileList"
    >
      <el-button size="small" type="primary">点击上传</el-button>
      <div slot="tip" class="el-upload__tip">
        只能上传jpg/png文件,且不超过500kb
      </div>
    </el-upload>
  </div>
</template>
<script>
export default {
  data() {
    return {
      fileList: [],
    };
  },
  methods: {
    handleChange(file, fileList) {
      console.log(file, fileList);
      // 从 fileList 数组中提取最后三个元素,并将结果赋值给 this.fileList。
      this.fileList = fileList.slice(-3);
    },
  },
};
</script>
最后更新时间' 2025/1/3 14:16:58