放肆青春的博客
首页
前端
算法
网络
面试
技术
后端
运维
杂项
数据库
工具
网址
电脑
个人
文章
  • 分类
  • 标签
  • 归档
github (opens new window)
gitee (opens new window)

放肆青春

一个前端菜鸟的技术成长之路
首页
前端
算法
网络
面试
技术
后端
运维
杂项
数据库
工具
网址
电脑
个人
文章
  • 分类
  • 标签
  • 归档
github (opens new window)
gitee (opens new window)
  • 前端

    • 前端 概览
    • 前端汇总

    • front 博文

    • front 项目总结

    • front 高级

    • front tools

  • vue

    • vue 概览
    • vue 汇总

    • vue 博文

    • vue 项目总结

      • vue 配置
      • vue环境
      • vue国际化
      • vue指令
        • vue 自定义指令
          • 指令代码如下
      • vue页面刷新
      • vue混入
      • vue-other
      • vue二维码
      • vue防抖节流
      • vue svg
      • vue图片
      • vue echarts图表
      • vue复制
    • vue 高级

  • html

    • html 概览
    • html 汇总

    • html 博文

  • css

    • css 概览
    • css 汇总

    • css 博文

    • sass

    • less

  • js

    • javascript 概览
    • JS 汇总

    • ES6

    • JS 博文

    • JS 工具

  • node

    • node 概览
    • node 汇总

    • node 框架

    • node 博文

  • react

    • react 概览
    • react 汇总

    • react 博文

    • react 高级

  • 微信小程序

    • 微信小程序 概览
    • 微信小程序总结
    • 微信小程序文章
    • 微信小程序 博文

    • 微信小程序 高级

  • 微信公众号

    • 微信公众号 概览
    • 微信公众号总结
    • 微信公众号文章
  • 多端开发

    • 多端开发
    • dsbridge 概览
    • jsbridge 概览
    • webview
    • uniapp

      • uniapp 概览
    • taro

      • taro 概览
    • flutter

      • flutter 概览
      • flutter 环境搭建
    • electron

      • electron 概览
  • front
放肆青春
2020-07-09

vue指令

# vue 自定义指令

  • 简介

    除了内置指令外, 用户自定义的指令
    自定义指令有全局和局部
    自定义指令都是 v-name 的模式,如:v-focus,name 是 directive()方法的第一个参数

  • 参数详解

  • 全局自定义指令

Vue.directive('focus', {
    inserted: function (el) {
      el.focus()
    }
})
1
2
3
4
5
  • 局部自定义指令
directives: {
  focus: {
    inserted: function(el) {
      el.focus();
    }
  }
},
1
2
3
4
5
6
7
  • 参数详解

    这个方法有两个参数,第一个就是自定义指令的名字,第二个参数是操作对象,这个对象里有几个钩子函数

    bind:绑定指令到元素上,只执行一次
    inserted:绑定了指令的元素插入到页面中展示时调用,基本上都是操作这个钩子函数
    update:所有组件节点更新时调用
    componentUpdated:指令所在组件的节点及其子节点全部更新完成后调用
    unbind:解除指令和元素的绑定,只执行一次

    钩子函数的参数有四个:

    el:就会指令所绑定的 DOM
    binding:一个包含 DOM 和指令的一些信息的对象
    vnode:就是编译生成的虚拟节点
    oldVnode:上一个虚拟节点

  • 指令封装

    • 目录

      | 1- directives
      | 2-- index.js
      | 2-- permission.js
      | 2-- data-input.js

    • index.js

      import dataInput from './data-input.js';
      import permission from './permission.js';
      const directives = [dataInput, permission];
      export default {
        install: Vue => {
          if (directives.length && directives.length > 0) {
            directives.map(item => {
              Vue.directive(item.key, item.func);
            });
          }
        }
      };
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
    • mian.js

      import Directives from '@/directives/index';
      Vue.use(Directives);
      
      1
      2
    • data-input.js(demo)

      // 页面使用: v-data-input="'int'"
      // 正则定义,需要定义相反的匹配正则,
      // 例子:如果需要input只能输入整数,则该正则需要为:非整数正则
      var intReg = /[^0-9]/gi; //
      const directiveType = (value, e) => {
        switch (value) {
          case 'num':
            break;
          case 'int':
            // 如果不符合正则才替换
            if (intReg.test(e.target.value)) {
              e.target.value = e.target.value.replace(intReg, '');
              // 调用input事件使vue v-model绑定更新
              e.target.dispatchEvent(new Event('input'));
            }
            break;
          case 'float':
            break;
        }
      };
      
      /**
      * @author LeeYunxiang
      * @description 限制数字输入格式 int => 正整数 ,
      * num => 自然数(正整数包括0) ,
      * float => 正数包括小数(建议用text类型的input表单)
      **/
      export default {
        key: 'data-input',
        func: {
          // 当绑定了指令的这个HTML元素插入到父元素上时触发
          // (在这里父元素是 `div#app`)**.但不保证,父元素已经插入了 DOM 文档
          bind(el, binding) {
            const target = el instanceof HTMLInputElement ? el : el.querySelector('input');
            target.addEventListener('keydown', e => {
              if (binding.value) {
                directiveType(binding.value, e);
              }
            });
            // 兼容微软输入法及谷歌浏览器中文输入问题
            target.addEventListener('compositionend', e => {
              if (binding.value) {
                directiveType(binding.value, e);
              }
            });
            target.addEventListener('paste', e => {
              if (binding.value) {
                directiveType(binding.value, e);
              }
            });
            target.addEventListener('keyup', e => {
              if (binding.value) {
                directiveType(binding.value, e);
              }
            });
          }
        }
      };
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58

# 指令代码如下

  • 移动端拖拽指令
Vue.directive('movable', {
  bind(el) {
    let agent = window.navigator.userAgent.toLowerCase(),
      start,
      move,
      end
    //判断当前是移动端还是PC,移动端监听touch,PC监听mouse
    if (['android', 'iphone', 'symbianos', 'windows phone', 'ipad', 'ipod'].some((i) => agent.indexOf(i) > 0)) {
      start = 'touchstart'
      move = 'touchmove'
      end = 'touchend'
    } else {
      start = 'mousedown'
      move = 'mousemove'
      end = 'mouseup'
    }
    //添加事件开始监听
    el.addEventListener(start, (e) => {
      //读取事件开始时,触摸或鼠标按下的坐标,以及容器当前所在位置,并声明两个函数对象,供后面添加和取消监听用
      let cur = e.touches ? { x: e.touches[0].clientX, y: e.touches[0].clientY } : { x: e.clientX, y: e.clientY },
        x = el.offsetLeft,
        y = el.offsetTop,
        prevent = function() {
          event.preventDefault()
        },
        moveFun = function() {
          let wDom = 44;
          let hDom = 88;
          if (event.touches) {
            if (event.touches[0].clientX - cur.x + x > 0) {
              if (event.touches[0].clientX > screen.width) {
                el.style.left = screen.width - wDom + 'px'
              } else {
                el.style.left = event.touches[0].clientX - cur.x + x + 'px'
              }
            } else {
              el.style.left = 0 + 'px'
            }

            if (event.touches[0].clientY - cur.y + y > 0) {
              if (event.touches[0].clientY > screen.height - hDom) {
                el.style.top = screen.height - hDom + 'px'
              } else {
                el.style.top = event.touches[0].clientY - cur.y + y + 'px'
              }
            } else {
              el.style.top = 0 + 'px'
            }
          } else {
            if (event.clientX - cur.x + x > 0) {
              if (event.clientX > screen.width) {
                el.style.left = screen.width - wDom + 'px'
              } else {
                el.style.left = event.clientX - cur.x + x + 'px'
              }
            } else {
              el.style.left = 0 + 'px'
            }
            if (event.clientY - cur.y + y > 0) {
              if (event.clientY > screen.height - hDom) {
                el.style.top = screen.height - hDom + 'px'
              } else {
                el.style.top = event.clientY - cur.y + y + 'px'
              }
            } else {
              el.style.top = 0 + 'px'
            }
          }
          // 阻止移动端屏幕移动
          window.addEventListener('touchmove', prevent, { passive: false })
        }
      //监听move并修改位置
      el.addEventListener(move, moveFun)
      //声明一个移除处理函数对象
      let endFun = function() {
        el.removeEventListener(move, moveFun)
        el.removeEventListener(move, endFun)
        window.removeEventListener('touchmove', prevent)
      }
      //监听到事件结束时,移除start以外的监听
      el.addEventListener(end, endFun)
    })
  },
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
更新时间: 3/22/2021, 4:43:19 PM
vue国际化
vue页面刷新

← vue国际化 vue页面刷新→

最近更新
01
前端权限管理
02-24
02
vue2指令
02-24
03
vue2 hook
02-24
更多文章>
Theme by Vdoing | Copyright © 2019-2022 放肆青春
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式