一些自定义指令封装

160 阅读1分钟
1.v-webp

结合ImageminWebpWebpackPlugin()插件使用,该插件可将指定图片文件资源转换成webp格式,提高文件加载速度,但使用该插件后打包出的文件与源文件对比多了个.webp后缀,需要手动修改引用地址很麻烦,添加v-webp指令后可快速转换

 config.plugins.push(
    new ImageminWebpWebpackPlugin({       //将图片转换为webp格式文件  结合v-webp指令使用
      config: [
        {
          test: /\.(jpe?g|png)/,
          options: {
            quality: 95
          }
        }
      ],
      overrideExtension: false
    })
  )
 判断当前浏览器环境是否支持webp,如果支持自动切换webp图片,否则使用原来的图片
window.supportsWebP = (function () {
  var canvas = typeof document === 'object' ? document.createElement('canvas') : {}
  canvas.width = canvas.height = 1
  return canvas.toDataURL ? canvas.toDataURL('image/webp').indexOf('image/webp') === 5 : false
}())
const webp = {}
webp.install = (Vue, options = {}) => {
  Vue.directive('webp', {
    // 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
    bind: function (el, binding) {
      if (binding.value && window.supportsWebP) {
        let webpSrc = binding.value + '.webp'
        el.style.backgroundImage = 'url("' + webpSrc + '")'
        let image = new Image()
        image.src = webpSrc
        image.onerror = function () {
          if (this.errorTag) {
            return
          }
          this.errorTag = true
          if ((process.env.NODE_ENV === 'production')) {
            console.warn('webp背景加载出错,退回原先格式,请检查该图片路径和尺寸,错误链接为:' + webpSrc)
          }
          el.style.backgroundImage = 'url("' + binding.value + '")'
        }
      } else if (el.tagName.toLowerCase() === 'img' && el.src && el.src.indexOf('data:image') === -1 && window.supportsWebP) {
        var _src = el.src
        el.src = _src + '.webp'
        el.onerror = function () {
          if (this.errorTag) {
            return
          }
          this.errorTag = true
          console.warn('webp加载出错,退回原先格式,请检查该图片路径和尺寸,错误链接为:' + el.src)
          el.src = _src
        }
      }
    }
  })
}
export default webp
使用:
 <img v-webp class="prize-dialog-header" src="../../assets/live_2021/23.png" alt="">
2.v-clipboard 快捷复制粘贴
const clipboardDirective = {
  install(app) {
    let instance;
    app.directive("clipboard", {
      bind(el, binding) {
        if (!Clipboard.isSupported()) {
          binding.value.onError?.("当前环境不支持剪切板功能!");
          return;
        }
        el.setAttribute("data-clipboard-text", binding.value.writeText);
        instance = new Clipboard(el);
        instance.on("success", e => {
          console.log(e);
          e.clearSelection();
          if (binding.value.onSuccess instanceof Function) {
            binding.value.onSuccess();
          } else {
            popTip("复制成功", 1000);
          }
        });
        instance.on("error", e => {
          console.log(e)
          if (binding.value.onError instanceof Function) {
            binding.value.onError();
          } else {
            popTip("复制失败", 1000);
          }
        });
      },
      updated(el, binding) {
        el.setAttribute("data-clipboard-text", binding.value.writeText);
      },
      unbind() {
        instance.destroy();
      }
    });
  }
}

使用

 <div v-clipboard="{ writeText: "我被复制啦", onSuccess() {}, onError(err) {} }">
   复制
  </div>