vue自定义指令

217 阅读2分钟

vue自定义指令

基本的生命周期

参考官方文档:

cn.vuejs.org/v2/guide/cu…

v-download

下载文件指令

思路:

  1. 通过指令传入地址,然后对地址进行格式匹配。
  2. 符合正则的则为标准格式的地址,不符合的则添加约定的前缀
  3. 创建a标签,调用a标签的点击事件。
  4. 删除a标签。

bug:某些浏览器下载图片的,会直接在新的窗口打开图片。这是a标签下载的缺陷。

const portReg = /(http|https):\/\/([\w.]+\/?)\S*/; //地址格式匹配

const baseUrl = process.*env*.VUE_APP_REQUEST_URL; // 不同环境下,文件的前缀不同

const createElementA = (url) => {// 如果后端地址没有前缀,添加路径前缀

 if (!portReg.test(url)) {

  url = baseUrl + url;

 }

 const a = document.createElement("a");// 创建a标签

 a.href = url;

 a.download = url.split("//").pop();

 a.target = "_blank";

 a.click();

};

export default {

 bind(el, binding) {

  el.addEventListener("click", () => {

   const urlStr = binding.value;

   const urls = urlStr.split(",");

   if (urls.length === 0) return false;

   urls.forEach((url) => {

​    createElementA(url.trim());

   });

  });

 },

 unbind(el) {

  el.removeEventListener("click", el.handler);

 },

};
// 调用方式
<span v-download="path" class="current">下载</span>

v-loadImg

目标:图片地址为空或者路径错误,统一显示默认图片,而不是裂开的图片框。

思路:当触发img 的onerror事件后,将地址替换为事先设置的默认图片

const errorImg = require("@/assets/error.png");//项目中设置的默认图片
export default {
  bind(el, binding) {
    const src = binding.value;
    el.src = src;
    el.onerror = function () {
      el.src = errorImg;
    };
  },
};


<img v-loadImg="isShow" alt="" class="cus-home_logo" /> 

v-trimStartEnd

目标:失去焦点后,删除输入框的两端空格。 思路:给input添加change事件,输入完成后,trim删除两端空格,重新赋值

export default {
  inserted(el, binding, vNode) {
    el.addEventListener('change', (e) => {
      const { value } = e.target;
      const newValue = value.trim();
      if (vNode.data.model) {
        vNode.data.model.callback(newValue);
      } else {
        e.target.value = newValue;
      }
    });
  },
};
    <input v-model='value' v-trimStartEnd="value">

v-limitMaxLength

目标:限制输入框可输入的长度 思路:输入过程中检查输入长度,超出长度后,基于提醒,并截取规定的最大长度。

import Vue from 'vue';
const that = new Vue();
export default {
  inserted(el, binding, vnode) {
    el.addEventListener('input', (e) => {
      const { arg = 0 } = binding;
      const argInt = parseInt(arg, 10);
      const { value } = e.target;
      if (value.length > argInt) {
        that.$message.error(`该字段不能超出${arg}个字符`);
        if (vnode.data.model) {
          vnode.data.model.callback(value.substring(0, argInt));
        } else {
          e.target.value = value.substring(0, argInt);
        }
      }
    });
  },
};
    <input v-model='value' v-limitMaxLength:50="value">

如果要解决输入法的超出问题,可以在添加一个change事件,事件的方法和input事件一致。用于输入完成后,在截取最长字段。