vue指令
# vue 自定义指令
简介
除了内置指令外, 用户自定义的指令
自定义指令有全局和局部
自定义指令都是 v-name 的模式,如:v-focus,name 是 directive()方法的第一个参数参数详解
全局自定义指令
Vue.directive('focus', {
inserted: function (el) {
el.focus()
}
})
1
2
3
4
5
2
3
4
5
- 局部自定义指令
directives: {
focus: {
inserted: function(el) {
el.focus();
}
}
},
1
2
3
4
5
6
7
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.jsindex.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
12mian.js
import Directives from '@/directives/index'; Vue.use(Directives);
1
2data-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
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