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>複製代碼
相關文章
相關標籤/搜索