vue中自定义指令和自定义过滤器
自定义指令
自定义指令有两种定义形式:
1 . 全局自定义指令
2 . 局部自定义指令
举个聚焦输入框的例子,如下:
全局自定义指令
//在main.js中用 vue.directive()
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
局部自定义指令
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}
}
然后你可以在模板中任何元素上使用新的 v-focus property,如下:
<input v-focus>
钩子函数
自定义指令定义提供了以下几个钩子函数
- bind( ){ }:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作
- inserted( ){ }:被绑定元素插入父节点时调用( 父节点存在即可调用, 不必存在于document 中)
- update( ){ }:被绑定元素所在的模板更新时调用,而不论绑定值是否变化
- componentUpdated( ){ }:被绑定元素所在模板完成一次更新周期时调用
- unbind( ){ }:只调用一次, 指令与元素解绑时调用
钩子函数参数
-
el:指令所绑定的元素,可以用来直接操作 DOM。
-
binding:一个对象,包含以下 property:
name:指令名,不包括 v- 前缀。 value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。 oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。 expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。 arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。 modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
-
vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
-
oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。
使用场景: 当我们需要对普通的DOM元素进行底层操作时就可以用到自定义指令
这是一个使用了这些 property 的自定义钩子样例:
<div id="hook-arguments-example" v-demo:foo.a.b="message"></div>
Vue.directive('demo', {
bind: function (el, binding, vnode) {
var s = JSON.stringify
el.innerHTML =
'name: ' + s(binding.name) + '<br>' +
'value: ' + s(binding.value) + '<br>' +
'expression: ' + s(binding.expression) + '<br>' +
'argument: ' + s(binding.arg) + '<br>' +
'modifiers: ' + s(binding.modifiers) + '<br>' +
'vnode keys: ' + Object.keys(vnode).join(', ')
}
})
new Vue({
el: '#hook-arguments-example',
data: {
message: 'hello!'
}
})
自定义过滤器
过滤器是实现变量的格式化输出 。
过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。
<!-- 在双花括号中 -->
{{ message | capitalize }}
<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>
过滤器分为局部过滤器还有全局过滤器
全局过滤器 是在多个实例中可以使用的过滤器
Vue.filter(“名”,function(value,value2){
// value是调用过滤器的属性的值
//value2是要传入的值
})
调用:
{{ 属性 | 过滤器名}}
局部过滤器 只是在当前的组件或者实例中使用
filters:{
名:function(val){
}
}
注意:过滤器可以串联 但是后面的肯定是以前面的为基础
变量 | 过滤器1 | 过滤器2
{{ message | filterA | filterB }}
在这个例子中,filterA 被定义为接收单个参数的过滤器函数,表达式 message 的值将作为参数传入到函数中。然后继续调用同样被定义为接收单个参数的过滤器函数 filterB,将 filterA 的结果传递到 filterB 中。
过滤器是 JavaScript 函数,因此可以接收参数:
{{ message | filterA('arg1', arg2) }}
这里,filterA 被定义为接收三个参数的过滤器函数。其中 message 的值作为第一个参数,普通字符串 ‘arg1’ 作为第二个参数,表达式 arg2 的值作为第三个参数。
补零案例
首字母大写
保留两位小数
//全局
Vue.filter('time', (ee) => {
return ee.padStart(2, '0')
})
//局部
<template>
<div class="wrapper">
<br />
<input type="text" v-model="value" />
<br />
<p>{{value | num2}}</p>
<br />
<p>{{value | num}}</p>
<p>{{value | time}}</p>
</div>
</template>
<script>
export default {
data() {
return {
value: ''
}
},
filters: {
num(e){
//价钱补零
// //parseFloat 将数字转换为浮点型,否则会报错
// //2代表小数点后的长度
// 保留两位小数
return parseFloat(e).toFixed(2)
},
num2(e){
// 补零
return e.padStart(2,'0')
},
capitalize(value) {
// 首字母大写
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase()+ value.slice(1)
}
}
</script>
下面是常用的自定义过滤器
//去除空格 type 1-所有空格 2-前后空格 3-前空格 4-后空格
function trim(value, trim) {
switch (trim) {
case 1:
return value.replace(/\s+/g, "");
case 2:
return value.replace(/(^\s*)|(\s*$)/g, "");
case 3:
return value.replace(/(^\s*)/g, "");
case 4:
return value.replace(/(\s*$)/g, "");
default:
return value;
}
}
//任意格式日期处理
//使用格式:
// {{ '2018-09-14 01:05' | formaDate(yyyy-MM-dd hh:mm:ss) }}
// {{ '2018-09-14 01:05' | formaDate(yyyy-MM-dd) }}
// {{ '2018-09-14 01:05' | formaDate(MM/dd) }} 等
function formaDate(value, fmt) {
var date = new Date(value);
var o = {
"M+": date.getMonth() + 1, //月份
"d+": date.getDate(), //日
"h+": date.getHours(), //小时
"m+": date.getMinutes(), //分
"s+": date.getSeconds(), //秒
"w+": date.getDay(), //星期
"q+": Math.floor((date.getMonth() + 3) / 3), //季度
"S": date.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o) {
if(k === 'w+') {
if(o[k] === 0) {
fmt = fmt.replace('w', '周日');
}else if(o[k] === 1) {
fmt = fmt.replace('w', '周一');
}else if(o[k] === 2) {
fmt = fmt.replace('w', '周二');
}else if(o[k] === 3) {
fmt = fmt.replace('w', '周三');
}else if(o[k] === 4) {
fmt = fmt.replace('w', '周四');
}else if(o[k] === 5) {
fmt = fmt.replace('w', '周五');
}else if(o[k] === 6) {
fmt = fmt.replace('w', '周六');
}
}else if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
return fmt;
}
//字母大小写切换
/*type
1:首字母大写
2:首页母小写
3:大小写转换
4:全部大写
5:全部小写
* */
function changeCase(str, type) {
function ToggleCase(str) {
var itemText = ""
str.split("").forEach(
function (item) {
if (/^([a-z]+)/.test(item)) {
itemText += item.toUpperCase();
} else if (/^([A-Z]+)/.test(item)) {
itemText += item.toLowerCase();
} else {
itemText += item;
}
});
return itemText;
}
switch (type) {
case 1:
return str.replace(/\b\w+\b/g, function (word) {
return word.substring(0, 1).toUpperCase() + word.substring(1).toLowerCase();
});
case 2:
return str.replace(/\b\w+\b/g, function (word) {
return word.substring(0, 1).toLowerCase() + word.substring(1).toUpperCase();
});
case 3:
return ToggleCase(str);
case 4:
return str.toUpperCase();
case 5:
return str.toLowerCase();
default:
return str;
}
}
//字符串循环复制,count->次数
function repeatStr(str, count) {
var text = '';
for (var i = 0; i < count; i++) {
text += str;
}
return text;
}
//字符串替换
function replaceAll(str, AFindText, ARepText) {
raRegExp = new RegExp(AFindText, "g");
return str.replace(raRegExp, ARepText);
}
//字符替换*,隐藏手机号或者身份证号等
//replaceStr(字符串,字符格式, 替换方式,替换的字符(默认*))
//ecDo.replaceStr('18819322663',[3,5,3],0)
//result:188*****663
//ecDo.replaceStr('asdasdasdaa',[3,5,3],1)
//result:***asdas***
//ecDo.replaceStr('1asd88465asdwqe3',[5],0)
//result:*****8465asdwqe3
//ecDo.replaceStr('1asd88465asdwqe3',[5],1,'+')
//result:"1asd88465as+++++"
function replaceStr(str, regArr, type, ARepText) {
var regtext = '',
Reg = null,
replaceText = ARepText || '*';
//repeatStr是在上面定义过的(字符串循环复制),大家注意哦
if (regArr.length === 3 && type === 0) {
regtext = '(\\w{' + regArr[0] + '})\\w{' + regArr[1] + '}(\\w{' + regArr[2] + '})'
Reg = new RegExp(regtext);
var replaceCount = this.repeatStr(replaceText, regArr[1]);
return str.replace(Reg, '$1' + replaceCount + '$2')
}
else if (regArr.length === 3 && type === 1) {
regtext = '\\w{' + regArr[0] + '}(\\w{' + regArr[1] + '})\\w{' + regArr[2] + '}'
Reg = new RegExp(regtext);
var replaceCount1 = this.repeatStr(replaceText, regArr[0]);
var replaceCount2 = this.repeatStr(replaceText, regArr[2]);
return str.replace(Reg, replaceCount1 + '$1' + replaceCount2)
}
else if (regArr.length === 1 && type === 0) {
regtext = '(^\\w{' + regArr[0] + '})'
Reg = new RegExp(regtext);
var replaceCount = this.repeatStr(replaceText, regArr[0]);
return str.replace(Reg, replaceCount)
}
else if (regArr.length === 1 && type === 1) {
regtext = '(\\w{' + regArr[0] + '}$)'
Reg = new RegExp(regtext);
var replaceCount = this.repeatStr(replaceText, regArr[0]);
return str.replace(Reg, replaceCount)
}
}
//格式化处理字符串
//ecDo.formatText('1234asda567asd890')
//result:"12,34a,sda,567,asd,890"
//ecDo.formatText('1234asda567asd890',4,' ')
//result:"1 234a sda5 67as d890"
//ecDo.formatText('1234asda567asd890',4,'-')
//result:"1-234a-sda5-67as-d890"
function formatText(str, size, delimiter) {
var _size = size || 3, _delimiter = delimiter || ',';
var regText = '\\B(?=(\\w{' + _size + '})+(?!\\w))';
var reg = new RegExp(regText, 'g');
return str.replace(reg, _delimiter);
}
//现金额大写转换函数
//ecDo.upDigit(168752632)
//result:"人民币壹亿陆仟捌佰柒拾伍万贰仟陆佰叁拾贰元整"
//ecDo.upDigit(1682)
//result:"人民币壹仟陆佰捌拾贰元整"
//ecDo.upDigit(-1693)
//result:"欠人民币壹仟陆佰玖拾叁元整"
function upDigit(n) {
var fraction = ['角', '分', '厘'];
var digit = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
var unit = [
['元', '万', '亿'],
['', '拾', '佰', '仟']
];
var head = n < 0 ? '欠人民币' : '人民币';
n = Math.abs(n);
var s = '';
for (var i = 0; i < fraction.length; i++) {
s += (digit[Math.floor(n * 10 * Math.pow(10, i)) % 10] + fraction[i]).replace(/零./, '');
}
s = s || '整';
n = Math.floor(n);
for (var i = 0; i < unit[0].length && n > 0; i++) {
var p = '';
for (var j = 0; j < unit[1].length && n > 0; j++) {
p = digit[n % 10] + unit[1][j] + p;
n = Math.floor(n / 10);
}
s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s;
//s = p + unit[0][i] + s;
}
return head + s.replace(/(零.)*零元/, '元').replace(/(零.)+/g, '零').replace(/^整$/, '零元整');
}
//保留2位小数
function toDecimal2(x){
var f = parseFloat(x);
if (isNaN(f)) {
return false;
}
var f = Math.round(x * 100) / 100;
var s = f.toString();
var rs = s.indexOf('.');
if (rs < 0) {
rs = s.length;
s += '.';
}
while (s.length <= rs + 2) {
s += '0';
}
return s;
}
export{
trim,
changeCase,
repeatStr,
replaceAll,
replaceStr,
checkPwd,
formatText,
upDigit,
toDecimal2,
formaDate
}