vue常用指令

2020-09-15  本文已影响0人  w_小伍

1来源https://juejin.im/post/6872128694639394830

1.限制input只能输入正整数
在src下新建directives,里面新建一个index.js
index.js

import Vue from 'vue'

Vue.directive('enterIntNumber', {
  inserted: function (el) {
    let trigger = (el, type) => {
      const e = document.createEvent('HTMLEvents')
      e.initEvent(type, true, true)
      el.dispatchEvent(e)
    }
    el.addEventListener("keyup", function (e) {
      let input = e.target;
      let reg = new RegExp('^\\d{1}\\d*$');  //正则验证是否是数字
      let correctReg = new RegExp('\\d{1}\\d*');  //正则获取是数字的部分
      let matchRes = input.value.match(reg);
      if (matchRes === null) {
        // 若不是纯数字 把纯数字部分用正则获取出来替换掉
        let correctMatchRes = input.value.match(correctReg);
        if (correctMatchRes) {
          input.value = correctMatchRes[0];
        } else {
          input.value = "";
        }
      }
      trigger(input, 'input')
    });
  }
});

在main.js引入

import './directives/index'

页面使用

<input type="text" v-enterIntNumber v-model='msg'>

1.1输入正整数和浮点数

import Vue from 'vue'
import {checkNumber, checkFloat} from '@/utils/common'

Vue.directive('vueOnkeypress', {
  bind: function (el, binding, vnode) {
    let val = binding.value
    if (val === 'number') {
      el.onkeypress = function (e) {
        return checkNumber(e)
      }
    }
    if (val === 'float') {
      el.onkeypress = function (e) {
        return checkFloat(e)
      }
    }
    // el.oninput = function (e) {
    //   if (e.target.value.length > val.max) {
    //     e.target.value = e.target.value.slice(0, val.max)
    //     console.log(e.target.value)
    //   }
    // }
  }
})

v-vue-onkeypress="inputType.number"
v-vue-onkeypress="inputType.float"
inputType: { // input输入类型
          number: 'number',
          float: 'float'
        },

2,3来源https://www.cnblogs.com/dhui/p/13268040.html

2.点击空白地方隐藏div(不兼容ie)
在index.js里

Vue.directive('clickoutside', {
  bind(el, binding) {
    const self = {} // 定义一个私有变量,方便在unbind中可以解除事件监听
    self.documentHandler = (e) => {
      // contains不兼容ie
      if (el.contains(e.target)) { // 这里判断绑定的元素是否包含点击元素,如果包含则返回
        return false
      }
      if (binding.value) { // 判断指令中是否绑定了值
        binding.value(e) // 如果绑定了函数则调用那个函数,此处 binding.value就是handleClose方法
      }
      return true
    }
    document.addEventListener('click', self.documentHandler)
  },
  unbind(el) {
    // 解除事件监听
    document.removeEventListener('click', self.documentHandler)
    delete self.documentHandler
  }
});

使用

<div v-show="show" v-clickoutside="handleClickOutside" style="width: 100px;height: 100px;background-color: pink;"></div>

handleClickOutside() {
        this.show = false
      },

3.自定义指令来优化图片的加载:图片在加载过程中,未加载完成时使用灰色背景占位,图片加载完后直接显示
index.js里

Vue.directive('imgUrl', function (el, binding) {
  el.style.backgroundColor = '#FEFEFE' //设置背景颜色
  var img = new Image()
  img.src = binding.value // binding.value 指令后的参数
  img.onload = function () {
    el.style.backgroundColor = ''
    el.src = binding.value
  }
})

使用

 <!-- 参数不可以直接填写url地址-->
        <img v-imgUrl='url' /> 
export default {
        data () {
            return {
                url: '../src/assets/logo.png'
            }
        }
    }

4.弹窗拖拽
index.js

Vue.directive('dialogDragMove', {
  bind(el, binding, vnode, oldVnode) {
    const dragDom = el.querySelector('.rl-inner') // 整个内容区
    const dialogHeaderEl = el.querySelector('.popup-title') // 可以使用拖拽的位置
    dialogHeaderEl.style.cursor = 'move'
    // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
    const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null)
    dialogHeaderEl.onmousedown = (e) => {
      // 鼠标按下,计算当前元素距离可视区的距离
      const disX = e.clientX - dialogHeaderEl.offsetLeft
      const disY = e.clientY - dialogHeaderEl.offsetTop
      // 获取到的值带px 正则匹配替换
      let styL, styT
      // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
      if (sty.left.includes('%')) {
        styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100)
        styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100)
      } else {
        styL = +sty.left.replace(/px/g, '')
        styT = +sty.top.replace(/px/g, '')
      }
      document.onmousemove = function (e) {
        // 通过事件委托,计算移动的距离
        const l = e.clientX - disX
        const t = e.clientY - disY
        // 移动当前元素
        dragDom.style.left = `${l + styL}px`
        dragDom.style.top = `${t + styT}px`
        // 将此时的位置传出去
        // binding.value({x:e.pageX,y:e.pageY})
      }
      document.onmouseup = function (e) {
        document.onmousemove = null
        document.onmouseup = null
      }
    }
  }
})

使用

<div class="popup-wrap" v-dialogDragMove>
      <div class="rl-inner">
        <div class="popup-title"></div>
      </div>
    </div>

css
.popup-wrap {
    position: fixed;
    width: 100%;
    height: 100%;
    left: 0;
    right: 0;
    top: 0;
    background: rgba(0,0,0,0.3);
  }
  .rl-inner {
    position: absolute;
    width: 400px;
    min-height: 200px;
    background-color: #fff;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
  }
  .popup-title {
    height: 30px;
    width: 100%;
    background: #f0f9eb;
  }
上一篇下一篇

猜你喜欢

热点阅读