Element-ui的头像上传组件封装v-model

2,720 阅读1分钟

起因

头像上传的组件,传值只能手动添加,不方便

都是给表单赋值,别的组件有v-model双向绑定,那就给头像上传组件也封装一个

实现

  • v-model只是propsemit的一个语法糖
    • props传值的时候,属性名一定要是value
    • emit的方法名也一定要是input,且传的参一定要是value属性对应的值
  1. 创建一个组件,例upload.vue
  2. 复制element-uiel-upload相关代码
  3. 定义接口地址,接口参数名,图片地址
  4. 在上传成功的回调函数handleAvatarSuccess,调用input方法,传参
<template>
  <el-upload
    name="接口参数名"
    class="avatar-uploader"
    :action="接口地址"
    :show-file-list="false"
    :on-success="handleAvatarSuccess"
    :before-upload="beforeAvatarUpload"
  >
    <img v-if="value" :src="接口基地址 + value" class="avatar" />
    <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  </el-upload>
</template>

<script>
export default {
  props: ['value'],
  methods: {
    handleAvatarSuccess(res, file) {
      this.$emit('input', res.data.file_path); // ++
    },
    beforeAvatarUpload(file) {
      const isJPG = file.type === 'image/jpeg';
      const isLt2M = file.size / 1024 / 1024 < 2;

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

<style>
.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}
.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  line-height: 178px;
  text-align: center;
}
.avatar {
  width: 178px;
  height: 178px;
  display: block;
}
</style>

父组件使用

<template>
  <div>
    <h3>上传组件</h3>
    <!-- <upload :value="imageUrl" @input="inputEvent"></upload> -->
    <hr />
    <upload v-model="imageUrl"></upload>
  </div>
</template>

<script>
import upload from './components/upload'
export default {
  components: {
    upload
  },
  data () {
    return {
      imageUrl: ''
    }
  },
  methods: {
    // inputEvent (src) {
    //   this.imageUrl = src
    // }
  }
}
</script>

<style></style>