c语言编程笔录

首页 >   > 笔记大全

笔记大全

Vue中8个实用的自定义指令分享

更新时间:2023-12-01

介绍Vue中8个实用的自定义指令

Vue中的自定义指令可以让开发者在模板中将普通的HTML属性转换成具有特定功能的指令。Vue自带了很多自定义指令,但我们也可以通过编写自己的指令来扩展Vue的功能。以下是8个实用的自定义指令。

v-click-outside

这个指令可以用来捕获元素外面的鼠标点击事件。


Vue.directive('click-outside', {
  bind: function(el, binding, vnode) {
    el.clickOutsideEvent = function(event) {
      // 判断是否在指令元素内部点击
      if (!(el == event.target || el.contains(event.target))) {
        // 如果是,则触发表达式中的函数
        vnode.context[binding.expression](event);
      }
    };
    document.body.addEventListener('click', el.clickOutsideEvent)
  },
  unbind: function(el) {
    document.body.removeEventListener('click', el.clickOutsideEvent)
  },
});

v-focus

这个指令可以自动聚焦到元素。


Vue.directive('focus', {
  inserted: function(el) {
    el.focus();
  },
});

v-debounce

这个指令可以让方法的执行被延迟到一定时间后,以减少方法的调用次数。


Vue.directive('debounce', {
  inserted: function(el, binding) {
    let timer;
    el.addEventListener('keyup', function() {
      clearTimeout(timer);
      timer = setTimeout(function() {
        binding.value();
      }, 500);
    })
  }
});

v-throttle

这个指令可以让方法在一定时间间隔内只执行一次,以减少方法的调用次数。


Vue.directive('throttle', {
  inserted: function(el, binding) {
    let timer;
    let limit = binding.arg || 500;
    el.addEventListener('click', function() {
      clearTimeout(timer);
      timer = setTimeout(function() {
        binding.value();
      }, limit);
    })
  }
});

v-scroll

这个指令可以让方法在元素滚动时触发。


Vue.directive('scroll', {
  inserted: function(el, binding) {
    let f = function(evt) {
      if (binding.value(evt, el)) {
        window.removeEventListener('scroll', f)
      }
    };
    window.addEventListener('scroll', f)
  }
});

v-longpress

这个指令可以让方法在长按元素时触发。


Vue.directive('longpress', {
  bind: function(el, binding) {
    let pressTimer = null;
    let handle = function(evt) {
      binding.value(evt);
    };
    let start = function(evt) {
      if (evt.type === 'click' && evt.button !== 0) {
        return;
      }
      if (pressTimer === null) {
        pressTimer = setTimeout(function() {
          handle(evt);
        }, 1000);
      }
    };
    let cancel = function() {
      if (pressTimer !== null) {
        clearTimeout(pressTimer);
        pressTimer = null;
      }
    };
    el.addEventListener('mousedown', start);
    el.addEventListener('touchstart', start);
    el.addEventListener('click', cancel);
    el.addEventListener('mouseout', cancel);
    el.addEventListener('touchend', cancel);
    el.addEventListener('touchcancel', cancel);
  },
});

v-ellipsis

这个指令可以让超出元素宽度的文字省略号代替并显示提示信息。


Vue.directive('ellipsis', {
  inserted: function(el, binding) {
    let tooltip = binding.value || el.innerText;
    el.setAttribute('title', tooltip);
    let style = window.getComputedStyle(el, null);
    let w = parseInt(style.getPropertyValue('width'));
    let pw = parseInt(style.getPropertyValue('padding-right'));
    let fs = parseInt(style.getPropertyValue('font-size'));
    let content = el.innerText;
    while (el.scrollWidth > w - pw && content.length > 0) {
      content = content.slice(0, -1);
      el.innerText = content + '...';
    }
  },
});

v-enter

这个指令可以让方法在按下enter键时触发。


Vue.directive('enter', {
  bind: function(el, binding) {
    el.addEventListener('keydown', function(evt) {
      if (evt.key === 'Enter') {
        binding.value(evt);
      }
    })
  },
});