vue 自定义指令

4 篇文章 0 订阅

Vue 自定义指令

自定义指令的钩子函数

  • bind:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个绑定时执行一次的初始化动作
  • inserted:被绑定元素插入父节点时调用(父节点存在即可调用,不必存在与document中)
  • update:被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新
  • componentUpdated:被绑定元素所在模板完成一次更新周期时调用
  • unbind:只调用一次,指令与元素解绑时调用
Vue.directive("test",{
  bind:function(el,binding,vnode){
    var keys = [];
    for(var i in vnode){
      keys.push(i)
    }
    el.innerHTML = 
      'name:'+binding.name + '<br>' +
      'value:' + binding.value + '<br>' +
      'expression:' + binding.expression +'<br>' +
      'argument:' + binding.arg +'<br>' +
      'modifiers:' + JSON.stringify(binding.modifiers) + '<br>' +
      'vnode keys:' + keys.join(',')
  }
})
 <div v-test:msg.a.b.c="message"></div>

请添加图片描述

  • el 指令绑定的元素,可以用来直接操作DOM
  • binding 一个对象,包含以下属性:
    • name 指令名
    • value 指令的绑定值
    • oldValue 指令绑定的前一个值,在update和componentUpdate钩子中可用。
    • expression 绑定值的字符串形式
    • arg 传给指令的参数
    • modifiers 一个包含修饰符的对象

input 输入框失去焦点时,提交数据,点击取消不提交数据,但是blur是失去焦点事件,当点击button按钮时,也会触发blur这个失去焦点事件,达不到我们的预期效果,下面使用vue指令 来实现这一效果。
判断绑定元素中是否包含我们当前点击的元素,如果包含,就返回false,否则就执行失去焦点事件的回调

Vue.directive("clickoutside", {
  bind: function (el, binding) {
    function documentHandler(e) {
      console.log(e);
      console.log(el.contains(e.target));
      
      if (el.contains(e.target)) {
        return false;
      }
      if (binding.expression) {
        binding.value()
      }
    }
    el._vueClickOutside_ = documentHandler;
    document.addEventListener("click", documentHandler);
  },
  unbind: function (el) {
    document.removeEventListener("click", el._vueClickOutside_);
    delete el._vueClickOutside_;
  },
});

new Vue({
	...
	methods:{
		 handlerSubmit:function(){
	      console.log("提交数据")
	    },
	}
	...
})
<div v-clickoutside="handlerSubmit">
     <input ref="input" type="text" @blur="handlerSubmit">
     <button @click="handlerCancel">取消</button>
</div>

实时时间转换指令

  • 1分钟内,“刚刚”
  • 1分钟-1小时 “分钟”
  • 1小时-1天 “小时”
  • 1天-1月 “天”
  • 年月日

时间处理对象time

export default const time = {
  // 当前时间戳
  getTime(){
    const date = new Date()
    return date.getTime()
  },
  // 今天0时0分0秒的时间戳
  getTodayTime(){
    const date = new Date()
    date.setHours(0)
    date.setSeconds(0)
    date.setMinutes(0)
    date.setMilliseconds(0)
    return date.getTime()
  },
  // 今年1月1日0时0分0秒的时间戳
  getYearTime(){
    const date = new Date()
    date.setMonth(0)
    date.setDate(1)
    date.setHours(0)
    date.setMinutes(0)
    date.setSeconds(0)
    date.setMilliseconds(0)
    return date.getTime()
  },
  // 标准年月日
  getLastDate(time){
    const date = new Date(time);
    const month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1 ;
    const day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
    return date.getFullYear() + '-' + month + '-' + day;
  },
  getFormatTime(timestamp){
    const now = this.getTime();
    const today = this.getTodayTime();
    // const year = this.getYearTime();
    const timer = (now - timestamp)/1000;
    let tip="";
    if(timer<=0){
      tip="刚刚";
    }else if(Math.floor(timer/60) <=0){
      tip = "刚刚";
    }else if(timer <3600){
      tip = Math.floor(timer/60) + '分钟前';
    }else if(timer>3600 && (timestamp-today > 0)){
      tip = Math.floor(timer/3600) + "小时前";
    }else if(timer/86400<=31){
      tip = Math.floor(timer
        /86400) + '天前';
    }else{
      tip = this.getLastDate(timestamp);
    }
    return tip;
  }
}

指令

隔一分钟 调用一次

Vue.directive("time",{
  bind(el,binding){
    el.innerHTML = mytime.getFormatTime(binding.value);
    el._timeout_ = setInterval(()=>{
      el.innerHTML = mytime.getFormatTime(binding.value)
    },60000)
  },
  unbind(el){
    clearInterval(el._timeout_);
    delete el._timeout_
  }

})


	<div>
      <div v-time="timeNow"></div>
      <div v-time="timebefore"></div>
    </div>
const mybirthday = {
//根据时间戳计算当前多少天
  getFormatDay(value) {
    const nowTime = new Date().getTime()
    return Math.floor((nowTime-value)/86400000) + "天";
  },
  // 根据多少天计算出几年几月几日(即出生几岁几月几日)
  getYearMonthDay(value){
    const year = Math.floor(value/365)
    const month = Math.floor(value%365/30)
    const day = Math.floor(value%365%30)
    return year + "岁" + month + "个月" + day + "天"
  }
};
export default mybirthday;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值