Changes to the source code of the image preview plug-in in element-plus

Recently, there is a requirement that while previewing the image, you can enlarge, reduce, rotate, view the original image (after enlarging or reducing) and other functions. To put it bluntly, this is a picture editor. Now that this requirement has been raised, we must find ways to realize it.
Let’s talk about the project background first: PC-side project, the project composition is vue3.2+vite+pinia+element-plusWait

Since we want to implement image preview, we must start with the ui component library element-plus and take a look at the component image picture in the official document In this part, I found that there is aimage preview function, and you canenlarge, reduce, rotate, and view the original image< /span>, etc., perfectly meet the needs. So I’m going to use this plug-in to implement it.

Although the image component meets the needs, it has a prerequisite that the preview function will be triggered only when the image itself is clicked.

code show as below:

<template>
  <div class="demo-image__preview">
    <el-image
      style="width: 100px; height: 100px"
      :src="url"
      :zoom-rate="1.2"
      :max-scale="7"
      :min-scale="0.2"
      :preview-src-list="srcList"
      :initial-index="4"
      fit="cover"
    />
  </div>
</template>

<script lang="ts" setup>
const url =
  'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg'
const srcList = [
  'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
  'https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg',
  'https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg',
  'https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg',
  'https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg',
  'https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg',
  'https://fuss10.elemecdn.com/2/11/6535bcfb26e4c79b48ddde44f4b6fjpeg.jpeg',
]
</script>

<style scoped>
.demo-image__error .image-slot {
    
    
  font-size: 30px;
}
.demo-image__error .image-slot .el-icon {
    
    
  font-size: 30px;
}
.demo-image__error .el-image {
    
    
  width: 100%;
  height: 200px;
}
</style>

Among thempreview-src-list is to enable the preview function, and there are some supporting parameter settings: zoom-rate, etc., < /span>

But the requirement of our project is to click the button to enter a preview page, directly display the preview image, and there is a list of file names on the left. Click the file name in the list to display all the images uploaded under this file name, and then perform a carousel preview, and at the same time There is a corresponding thumbnail carousel below the big picture preview. The large picture preview carousel and the thumbnail carousel form a linkage effect. When the big picture is carousel, the thumbnails below are also carouseled. The same goes for thumbnail carousels.

So corresponding modifications need to be carried out according to the demand points,
1. First of all, the effect of clicking the button to preview the picture (using < /span> 3. Realize the linkage effect of image preview carousel and thumbnail carousel; ); swiper plug-in 2. Secondly, realize the carousel display of thumbnails (Achieved using this component in element-plus);el-image-viewer

Let’s implement it step by step:
1.1, becauseel-imageThis component can only display the image carousel when the image is clicked, so we can only change other solutions. After exploration, we foundel-image-viewer This component is a veritable preview component, which is very suitable for development needs.

<el-image-viewer
  ref="allImageViewerList"
  v-if="isShow"
  :url-list="imageList"
  @switch="($event) => onSwitch($event, 'imageView')"
  :hideOnClickModal="true"
  @imageClick="imageClick"
/>

Directly pass in the image list url-list , and then display the corresponding carousel preview effect. This achieves the effect of clicking the button to display the preview carousel image.
Although the effect is displayed, some aspects still cannot meet our needs. For example, the preview image is in a fixed area, but because of the mouse wheel event, the preview image can be realized while scrolling Zoom in and out, so when scrolling up and down in the list area on the left, the preview image also zooms in and out. So the problem to be solved is to prohibit the scroll wheel event. How to disable it? It's not mentioned in the api documentation. Need to look at the source code.
I first looked at the source code in element-plus installed in node_modules,
and found that the registerEventListener method was triggered in onMounted,

vue.onMounted(() => {
    
    
      var _a, _b;
      registerEventListener();
      (_b = (_a = wrapper.value) == null ? void 0 : _a.focus) == null ? void 0 : _b.call(_a);
    });

registerEventListener method code is as follows, found in registerEventListenercore.useEventListener(document, “wheel”, mousewheelHandler), wheel listening event, There are also keyboard listening events;

const scopeEventListener = vue.effectScope();
function registerEventListener() {
    
    
      const keydownHandler = lodashUnified.throttle((e) => {
    
    
        switch (e.code) {
    
    
          case aria.EVENT_CODE.esc:
            props.closeOnPressEscape && hide();
            break;
          case aria.EVENT_CODE.space:
            toggleMode();
            break;
          case aria.EVENT_CODE.left:
            prev();
            break;
          case aria.EVENT_CODE.up:
            handleActions("zoomIn");
            break;
          case aria.EVENT_CODE.right:
            next();
            break;
          case aria.EVENT_CODE.down:
            handleActions("zoomOut");
            break;
        }
      });
      const mousewheelHandler = lodashUnified.throttle((e) => {
    
    
        const delta = e.deltaY || e.deltaX;
        handleActions(delta < 0 ? "zoomIn" : "zoomOut", {
    
    
          zoomRate: props.zoomRate,
          enableTransition: false
        });
      });
      scopeEventListener.run(() => {
    
    
        core.useEventListener(document, "keydown", keydownHandler);
        core.useEventListener(document, "wheel", mousewheelHandler);
      });
    }

How to cancel these listening events? (You can check the usage of effectScope first)
Found a method like unregisterEventListener

function unregisterEventListener() {
    
    
   scopeEventListener.stop();
}

Through unregisterEventListener, you can access the monitoring of wheel and keydown.

But the unregisterEventListener event cannot be obtained from outside our component because this component does not expose the unregisterEventListener method.
Therefore, the source code needs to be modified to expose this event;
The modified code is as follows:

expose({
    
    
  setActiveItem,
  unregisterEventListener
});

In this way, you can use the unregisterEventListener method in the page that references the el-image-viewer component to remove the listening events of the scroll wheel and keyboard.

1.2 After modifying the source code to solve this problem, there is a new problem, which is to achieve the effect of clicking on the image to jump or download. (Why is it said to jump or download here? Because if the file is pdf or excel, the preview image shows a fixed image. Clicking it will jump to the corresponding file preview page. If it is a zip or other file, click the fixed image. The image will be downloaded directly).
Because the picture list rendered by the el-image-viewer component does not have a click event, so the source code needs to be modified to add a picture click event;
el-image- The viewer component originally has close and switch events. Just add an imageClick parallel to them, and then emit the imageClick event.

function imgClick(url) {
    
    
   if (["jpg", "jpeg", "png", "gif", "bmp", "svg", "tif", "pcx", "tga", "exif", "fpx", "psd", "cdr", "pcd", "dxf", "ufo", "eps", "ai", "raw", "wmv", "webp", "avif", "apng", "heic", "heif"].includes(url == null ? void 0 : url.fileName.substring((url == null ? void 0 : url.fileName.lastIndexOf(".")) + 1).toLowerCase())) {
    
    
        return;
      }
   emit("imageClick", url);
}

Add this parameter in the source code. First, if the data type is in image format, there will be no response when clicking. Only non-image formats will have return values. After returning, they will be downloaded or previewed ( The processing done in the page that references the el-image-viewer component).

1.3
OK, the source code has been modified to meet the needs. Let me talk about the process of changing the source code and how to put the source code into the project after packaging.
The element-plus version I use is the latest one, 2.4.1
The steps are as follows

  1. Download element-plus source code

  2. Modify the corresponding component source code in the component in the packages in the downloaded source code project;

  3. After the modification is completed, npm run build is packaged, and the packaged file is dist;

  4. Take the element-plus folder under dist and replace the element-plus in node_modules in your project (note that the element-plus under dist packaged in the source code project may lack global.d.ts, package.json, README.md, etc. These files, so don’t forget to copy them in first (copy these files from the original element-plus to the current element-plus, and then replace the original element-plus);

  5. After doing this, I found that there was no change when starting the project. At this time, we need to clear the cache. How to clear the cache? First delete the .vite file in node_modules, and then add –force to dev in scripts in package.json, as follows:
    ”scripts": { “dev”: “vite --force”, “build”: “vite build”, “preview” : “vite preview” },



  6. After doing this, restart the project and find that the modifications to the source code have taken effect.

  7. Note: The source code project of element-plus now uses pnpm, so when installing dependencies after cloning the source code, pay attention;

After doing all this, you can use the el-image-viewer component in element-plus to achieve the effect of image preview (carousel, zoom in, zoom out, rotate, view the original image, etc.)

I will write another article about the thumbnail carousel below, I hope this article will be helpful to everyone.

Guess you like

Origin blog.csdn.net/xiaolinlife/article/details/134435052