Vue图片上传及预览

2020/10/25 Vue

TIPS

基于Vue, Element的图片上传组件, 可以直接使用 v-model 绑定图片地址

# MyUpload组件

<template>
  <div class="upload-container" v-loading="loading">
    <el-upload v-bind="attrs">
      <i v-show="!value" class="el-icon-plus"></i>

      <div v-show="value" class="picture-wrapper">
        <img :src="value" class="picture" />

        <div class="picture-mask">
          <i class="el-icon-zoom-in" @click.stop="handlePreview"></i>
          <i class="el-icon-delete" @click.stop="handleDelete"></i>
        </div>
        <!-- 此时是点击其他地方重新上传,也可以禁用点击上传,加个重新上传的按钮 -->
        <!-- 主动触发上传 this.$refs['upload'].$refs['upload-inner'].handleClick() -->
      </div>
    </el-upload>

    <viewer
      ref="viewer"
      :images="[value]"
      @inited="inited"
    >
      <img src="" style="display:none;" />
    </viewer>

    <!-- 或者是使用element-ui自带的图片查看 this.$refs.elImage.clickHandler(); -->
    <!-- <el-image
      ref="elImage"
      style="width:0px;height:0px;display:block;"
      :src="value"
      :preview-src-list="[value]">
    </el-image> -->
  </div>
</template>

<script>
import "viewerjs/dist/viewer.css";
import Viewer from "v-viewer/src/component.vue";
// v-viewer@1.5.1 不同版本引入方式不同

export default {
  name: "MyUpload",
  props: {
    value: {
      type: String,
      default: "",
    },
  },
  components: {
    Viewer,
  },
  computed: {
    attrs() {
      return {
        ...this.config,
        ...this.$attrs,
      };
    },
  },
  data() {
    return {
      loading: false,
      config: {
        action: "", // 必选参数,上传的地址
        showFileList: false, // 是否显示已上传文件列表
        listType: "", // 文件列表的类型
        accept: "", // 接受上传的文件类型(thumbnail-mode 模式下此参数无效)
        data: {}, // 上传时附带的额外参数
        headers: {}, // 设置上传的请求头部
        onSuccess: this.onSuccess, // 文件上传成功时的钩子
        beforeUpload: () => {}, // 上传文件之前的钩子,参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传。
        // 更多请参考element-ui的upload组件 https://element.eleme.cn/#/zh-CN/component/upload
      },
    };
  },
  methods: {
    inited(viewer) {
      this.$viewer = viewer;
    },
    handlePreview() {
      this.$viewer.show();
    },
    handleDelete() {
      this.bindData('')
    },
    onSuccess(url) {
      this.bindData(url)
    },
    bindData(data) {
      this.$emit("input", data);
    }
  },
};
</script>

<style lang="scss" scoped>
.upload-container {
  display: inline-block;
  .picture-wrapper {
    position: relative;
    width: 100%;
    height: 100%;
    .picture {
      width: 100%;
      height: 100%;
    }
    .picture-mask {
      position: absolute;
      width: 100%;
      height: 100%;
      left: 0;
      top: 0;
      cursor: default;
      text-align: center;
      opacity: 0;
      background-color: rgba($color: #000000, $alpha: 0.5);
      transition: opacity 0.3s;
      .el-icon-zoom-in,
      .el-icon-delete {
        color: #ffffff;
        font-size: 20px;
        cursor: pointer;
        margin: 0 10px;
      }
      &:hover {
        opacity: 1;
      }
    }
  }
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

# 使用

<template>
  <div>
    <my-upload v-model="imgSrc" />
  </div>
</template>

<script>
import MyUpload from "./MyUpload.vue";

export default {
  name: "index",
  component: {
    MyUpload,
  },
  data() {
    return {
      imgSrc: "",
    };
  },
  methods: {},
};
</script>

<style lang="scss" scoped>
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
最近更新: 2023年03月21日 14:47:21