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