给博客图片增加点击放大功能

博客的图片点击放大是很常见的需求. 今天突发奇想有了实现这个功能的思路, 就先把它撸出来吧.

首先这个博客系统用的是markdown语法, 解析成html后得到一堆html字符串. 由于要在<img>上绑定事件, 就不可以简单的v-html插入了, 于是转换另一种思路实现.

捉摸了一下, 由于<img/>不是固定的, 于是需要动态绑定, 而动态构建和动态组件可以让我实现这一功能.
以下是实现方法.

# 1. 创建模板字符串

const pattern = new RegExp('src=(\'.+\'|".+")');
const html = `${parser
                  .makeHtml(res.content)     //原本的markdown字符串
                  .split(/[ ]/)              //空格分开
                  .map(el => {               //分开后遍历 寻找img标签
                    //正则匹配
                    if(pattern.test(el)) {
                      const urls = el.split('=');
                      const url = urls[urls.length - 1].substr(1, urls[urls.length - 1].length - 2);
                      // eslint-disable-next-line no-param-reassign
                      // 绑定事件
                      return `${el} @click="showImgDialog('${url};)"`;
                    }
                    //不是img标签则直接返回
                    return el; 
                  })
                  .join(' ')                 //重新拼接成字符串
               }
               //增加模态框
               <el-dialog
                 :visible.sync="dialog.visible"
                 width="80%">
                 <el-row type="flex" justify="center">
                   <span>
                     <img :src="dialog.url"/>
                   </span>
                 </el-row>
               </el-dialog>`;

# 2. 构建组件

      //构建
      const compiled = Vue.compile(`<div>${html}</div>`);
      const cmp = {
        data() {
          return {
            dialog: {
              url: '',
              visible: false,
            },
          };
        },
        render: compiled.render,
        staticRenderFns: compiled.staticRenderFns,
        methods: {
          showImgDialog(url) {
            this.dialog = {
              url,
              visible: true,
            };
          },
        },
      };
      //注册组件
      this.component = Vue.component('htmlContent', cmp);

# 3. 使用

利用动态组件插入这个动态构建的组件就OK拉

    <component v-bind:is="component " class="html-content" v-highlight/>

效果图, 直接点开有图片的博客就可以预览了