美文网首页
vue常用指令

vue常用指令

作者: w_小伍 | 来源:发表于2020-09-15 15:30 被阅读0次

    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;
      }
    

    相关文章

      网友评论

          本文标题:vue常用指令

          本文链接:https://www.haomeiwen.com/subject/zflfyktx.html