This is the second day of my participation in Gwen Challenge

Big picture preview this function should be more common, such as in news reading, blog reading, the text of the picture, basically have an enlarged view function, so based on this, want to do a big picture preview mode component, do not perfect place I hope you can point out ~

Above all else, if you’re interested, scroll down:

1. Initialize the Cli project

Create a project using vue create with the following directory:

New img – large – mode folder under the components, respectively set up styles, utils, BgMask. Vue, index. Vue, then can also be a index in the components. The js file, for the use of registered components

2. img-large-mode

Analysis of main documents:

Mask page

<! -- BgMask.vue --> <template> <! Animation - package -- -- > < the transition name = "fade" v - if = "visible" > < div > <! <div class="bg-mask" :style="{width: bodyWidth + 'px', height: bodyHeight + 'px'}" @click="closeAll"> </div> <! <div class="content-box-body" :style="{width: bodyWidth + 'px', height: 0; (bodyHeight - 100) + 'px'}" @click="closeAll" @mousewheel="handleMousewheel"> <img :src="imgURL" alt class="img-custom" ref="customImg" :style="{ transform: `scale(${activeImg.scale}) rotate(${activeImg.rotate}deg)`, transition: ` ${aniOpenFlag && aniName} 0.12 s linear `} "/ > < / div > <! -- tool button - > < div class = "content - box - footer" > < abbr title = "zoom in" @ click = "enLarge" v - if = "_buttonOptions. EnLargeButton" > <span class="iconfont icon-fangda icon"></span> </abbr> V - if = "_buttonOptions narrowImgButton" > < span class = "iconfont icon - suoxiao icon" > < / span > < / abbr > < abbr title = "reduction" @click="initImg" v-if="_buttonOptions.initImgButton"> <span class="iconfont icon-huanyuan icon"></span> </abbr> <abbr Title =" left "@click="rotate('left')" V-if =" _buttonoptions. leftButton"> <span class="iconfont iconyouXuanzhuan Icon "> < / span > < / abbr > < abbr title =" right "@ click =" rotate (' right ') "v - if =" _buttonOptions. RightButton "> < span class =" iconfont Icon - xiangzuoxuanzhuan icon "> < / span > < / abbr > < abbr title =" download "v - if =" _buttonOptions. DownloadButton "> < span class="iconfont icon-xiazai icon"></span> </abbr> </div> </div> </transition> </template> <script> //import x from '' Export default {name: 'bg-mask', components: {}, data() {return {aniOpenFlag: true, activeImg: Rotate: 0}, rotate: 0}, rotate: 0}, rotate: 0}, function: props {// button configuration buttonOptions: {type: Object, default: function () {return {}}}, // image URL address imgData: {default: }, // Mask switch visible: {type: Boolean, required: true}}, computed: _buttonOptions() {let initOptions = {enLargeButton: true, narrowImgButton: true, initImgButton: true, leftButton: true, rightButton: true, downloadButton: true } return Object.assign(initOptions, this.buttonOptions) }, / / picture address imgURL () {if (Object. The prototype. ToString. Call (enclosing imgData) = = '[Object String]') {return enclosing imgData} else {  return '' } // if (Object.prototype.toString.call(this.imgData) == '[object Array]') { // return '' // } }, AniName () {return this.aniopenFlag? 'all' : 'none'}}, created() {// Listen for window changes and change the image size window.addeventListener ('resize', this.initmask)}, methods: Rotate (direction) {this.aniopenFlag = true let rotate = this.activeimg. rotate = direction == 'right' ? rotate + 90 : rotate - 90 this.activeImg.rotate = rotate }, // Narrow method narrowImg() {let scale = this.activeimg. scale scale -= 0.1 if (scale <= 0.1) {scale = 0.1} this.activeImg.scale = scale }, // enLarge() {let scale = this.activeimg. scale scale += 0.1 if (scale >= 5) {scale = 5} this.activeimg.scale = scale }, HandleMousewheel (e) {if (e.teltay < 0) {this.enLarge()} if (e.teltay > 0) {this.narrowImg()}}, InitMask () {this.bodyWidth = window.innerWidth this.bodyheight = window.innerheight}, {this.aniopenFlag = false this.activeimg = {scale: 1, rotate: 0}}, // close closeAll() {this.initimg () this.$emit('close')}}} </script> <style lang='less' scoped>... </style>Copy the code
<! -- components/img-large-mode/index.vue --> <template> <div class="img-large-mode"> <! <bg-mask :visible. Sync ="visible" V-if ="visible" @close="closeMask" :imgData="imgData" -- <bg-mask :visible. :buttonOptions="buttonOptions"></bg-mask> </div> </template> <script> //import x from '' import BgMask from './BgMask' Export default {components: {BgMask}, props: {}, data() {return {// Button configuration buttonOptions: {}, imgData: ", visible: false } }, computed: {}, methods: ImgData = opt.imgData this.buttonOptions = opt.buttonOptions. If (opt) {this.imgData = opt.buttonOptions } // Open this. Visible = true, / / close the mask method closeMask () {this. Visible = false let imgLargeDomArr = document. QuerySelectorAll (' img - large - mode ') / / Dom if (imglargedomarr.length > 0) {for (let I = 0; i < imgLargeDomArr.length; i++) { imgLargeDomArr[i].parentNode.removeChild(imgLargeDomArr[i]) } } } } } </script>Copy the code

Styles is an iconfot CSS while utils is a utility function.

The component registration

/* components/index.js */
// Import components
import imgLargeMode from "@/components/img-large-mode";
// Install method for use with vue.use () registration
const install = (Vue, option) = > {
  // Create a constructor to generate a Vue instance
  const componentInstance = Vue.extend(imgLargeMode);
  // Define the instantiation object
  let currentComponent = null;
  // Instantiate the object to mount the component under body
  const initInstance = () = > {
    currentComponent = new componentInstance();
    let componentEL = currentComponent.$mount().$el;
    document.body.appendChild(componentEL);
  };
  // Define the user to use the method, hang to the Vue
  Vue.prototype.$_openLargeMode = {
    show(opt) {
      initInstance();
      returncurrentComponent.show(opt); }}; };if (typeof window! = ="undefined" && window.Vue) {
  install(window.Vue);
}
export default {
  install,
  imgLargeMode
};
Copy the code

Then introduce it in main.js

.import imgLargeMode from "@/components/index.js"; Vue.use(imgLargeMode); .Copy the code

Simple to use

<template> <div class="use"> < button@click ="openMask"> click </button> </div> </template> <script> //import x from "export"  default { components: {}, data() { return {} }, computed: {}, methods: { openMask() { this.$_openLargeMode.show({ imgData: `https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2019/12/7/16ee08923006f96b~tplv-t2oaga2asx-image.image`,  buttonOptions: { downloadButton: false } }) } } } </script> <style lang='less' scoped> //@import url() </style>Copy the code

OK, the big picture preview component is almost complete, if you are interested, you can try it out

This is the first version, there are many deficiencies, back slowly upgrade, welcome to correct ~

Demo source address: Github

At the end of the article thanks & reference article: juejin.cn/post/696206…