elementui预览图片组件二次封装

原由

在elementui组件库中,el-image组件有个预览图片功能,比较简洁,可是和图片绑定在一块儿,咱们只想要一个单纯的预览组件,传递一个图片,经过事件方式,显示大图css

分析

经过查看elementui的代码,发如今image(el-image组件)目录中里面有一个image-viewer组件, el-image组件的预览功能也是经过这一个组件实现的,只是官方没有把这个组件单独暴露出来element-ui

这里就比较简单了,咱们能够使用手动导入组件的方式,引入image-viewer组件ide

image-viewer组件二次封装

这里大概作了三件事优化

  • 组件方式导入element的image-viewer组件
  • 使用$attrs和$listeners把上层的属性和方法,原封不动传递给image-viewer组件,不用手动处理属性和方法,除非添加额外的功能
  • 修改关闭按钮的样式
<template>
  <div>
    <el-image-viewer
      v-bind="$attrs"
      v-on="$listeners"
    />
  </div>
</template>

<script>
// 手动导入图片预览组件
import ElImageViewer from 'element-ui/packages/image/src/image-viewer'

export default {
  name: 'ImagePreview',
  components: { ElImageViewer }
}
</script>

<style lang="scss" scoped>
::v-deep .el-image-viewer__btn.el-image-viewer__close {
  color: #fff;
}
</style>复制代码

使用

<template>
  <div>
    <el-button type="primary" @click="handlePictureCardPreview"
      >大图预览</el-button
    >
    <image-preview
      v-if="dialogVisible"
      :on-close="
        () => {
          dialogVisible = false;
        }
      "
      :url-list="[dialogImageUrl]"
    />
  </div>
</template>

<script>
import ImagePreview from "@/components/ImagePreview";

export default {
  components: {
    ImagePreview,
  },
  data() {
    return {
      imageUrl:
        "https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1483731740,4186543320&fm=26&gp=0.jpg",
      dialogImageUrl: "",
      dialogVisible: false,
    };
  },
  methods: {
    // 预览
    handlePictureCardPreview() {
      this.dialogImageUrl = this.imageUrl;
      this.dialogVisible = true;
    }
  },
};
</script>复制代码

优化:点击mask遮罩层关闭图片预览

上面封装之后,能够很简单使用图片预览,美中不足的是,点击遮罩层,没法关闭大图预览,只能点击右上角关闭按钮,才会关闭预览,使用上不太方便ui

分析

在查看image-viewer组件的源码发现,关闭按钮绑定hide方法,用于关闭预览的,可是遮罩层没有绑定任何方法,遮罩层也没有对外暴露任何方法调用,难受~this

解决方法

  • 先获取image-viewer组件
  • 随后获取到遮罩层元素,给遮罩层绑定一个方法,点击时候,就调用image-viewer组件里的hdie方法,达到关闭的目的
  • 在卸载组件的时候,移除以前给遮罩层绑定的方法
  • 点击遮罩关闭预览,对外暴露一个标志,控制是否点击遮罩关闭预览

完整代码以下:url

<template>
  <div>
    <el-image-viewer
      ref="elImageViewer"
      v-bind="$attrs"
      v-on="$listeners"
    />
  </div>
</template>

<script>
import ElImageViewer from 'element-ui/packages/image/src/image-viewer'

export default {
  name: 'ImagePreview',
  components: { ElImageViewer },
  props: {
    // 点击mask是否隐藏大图
    maskhide: {
      type: Boolean,
      default: true
    }
  },
  mounted() {
    if (this.maskhide) {
      this.addHideToMask()
    }
  },
  methods: {
    addHideToMask() {
      this.$viewer = this.$refs.elImageViewer
      if (this.$viewer) {
        // 获取遮罩层元素
        const mask = this.$viewer.$el.querySelector('.el-image-viewer__mask')
        if (mask) {
          // 遮罩层增长点击事件,关闭预览
          mask.addEventListener('click', this.hide)
          // hook卸载事件,移除以前添加在mask元素的事件
          this.$once('hook:beforeMount', () => {
            mask && mask.removeEventListener('click', this.hide)
          })
        }
      }
    },
    hide() {
      this.$viewer && this.$viewer.hide()
    }
  }
}
</script>

<style lang="scss" scoped>
::v-deep .el-image-viewer__btn.el-image-viewer__close {
  color: #fff;
}
</style>复制代码
相关文章
相关标签/搜索