乐趣区

关于javascript:Vue2Vueclicomponent

工作中遇到了一个问题,须要对接口返回的数据进行解决。

 接口返回的:<img src="http://www.test.com/1.png" ... /> 你好 <img src="http://www.test.com/2.png" ... /> 你好,你好

理论须要的:
<ImgMsg url="http://www.test.com/1.png" /> 你好 <ImgMsg url="http://www.test.com/2.png" /> 你好,你好 

思考后,想到了一种形式,借助 component,将 img 替换为本人封装的 ImgMsg 组件(蕴含了占位图、算出最佳适合显示比例、预览性能等性能)。

具体实现须要进行如下步骤:

1. 配置项

// vue.config.js
module.exports = {
  ...
  /* 是否应用蕴含运行时编译器的 Vue 构建版本。设置为 true 后你就能够在 Vue 组件中应用 template 选项了,然而这会让你的利用额定减少 10kb 左右。(默认 false) */
  runtimeCompiler: true,
}

2. 全局注册


// components/Common/index.js
import Vue from 'vue'
imoort ImgMsg from '@/components/ImgMsg'

const components = [ImgMsg];

components.forEach(component => {Vue.component(component.name, component);
});

3. 组件中应用

<!-- MassMsg.vue -->
<template>
  <div>
    <component :is="massMsg"></component>
  </div>
</template>

<script>
export default {
  name: 'massMsg',
  data() {
    return {regImg: /<img((?!class="biaoqing").)*?>/gi,
      regDataSrc: /data-src="(.*?)"/,
    };
  },
  props: {
    item: {
      type: Object,
      default: () => {}
    }
  },
  computed: {massMsg() {
      const msg = this.item.content.replace(this.regImg, result => {let groups = this.regDataSrc.exec(result);
        if (groups) {return '<ImgMsg url="' + groups[1] + '"></ImgMsg>';
        }
        return result;
      });
      return {template: `<div>${msg}</div>`
      };
    }
  }
};
</script>

附:
ImgMsg 组件代码

<!-- ImgMsg.vue -->
<template>
  <img class="el-common-img" :src="imgSrc" @click="setPicPreviewVisible(url)" @load="loadImg($event, url)" @error="loadError" />
</template>

<script>
import M from '@store/mutations';
import imgLoading from '@assets/images/loading.gif';
import loadError from '@assets/images/loadError.png';
export default {
  name: 'imgMsg',
  data() {
    return {
      ImgMaxWidth: 170,
      ImgMaxHeight: 170,
      imgSrc: imgLoading
    };
  },
  props: {
    url: {
      type: String,
      default: ''
    }
  },
  watch: {url(newVal) {if (newVal) this.imgSrc = newVal;
    }
  },
  methods: {
    /**
     * 解决图片音讯显示大小
     */
    loadImg(e, url) {
      let imgTarget = e.target,
        img = document.createElement('img');

      img.onload = e => {
        let target = e.target;
        let {w, h} = this.getImgSize(this.ImgMaxWidth, this.ImgMaxHeight, target.width, target.height);
        imgTarget.width = w;
        imgTarget.height = h;
        this.imgSrc = url;
      };
      img.src = url || '';
    },
    getImgSize(mw, mh, w, h) {if (w > mw && h <= mh) {
        // 图片宽度大于最大值
        h *= mw / w;
        w = mw;
      } else if (w <= mw && h > mh) {
        // 图片宽度小于等于最大值
        w *= mh / h;
        h = mh;
      } else if (w > mw && h > mh) {
        // 图片宽度和高度均大于最大值
        if (w / h >= mw / mh) {
          // 宽高比大于默认比例
          h *= mw / w;
          w = mw;
        } else {
          // 宽高比小于等于默认比例
          w *= mh / h;
          h = mh;
        }
      }
      return {w, h};
    },
    /**
     * 预览图片
     */
    setPicPreviewVisible(url) {this.$store.commit(M.Chat.setPicPreviewVisible, true);
      this.$store.commit(M.Chat.setPicPreviewSrc, url);
    },
    /**
     * 加载谬误占位图片
     */
    loadError() {this.imgSrc = loadError;}
  }
};
</script>
退出移动版