当前位置: 首页 > news >正文

少侠请重新来过 - Vue学习笔记(五) - 指令

指令

指令(Directives)是带有 v- 前缀的特殊属性。指令属性的值预期是单一 JavaScript 表达式。指令的职责就是当其表达式的值改变时相应地将某些行为应用到 DOM 上。

自定义指令

自定义指令是指,我们可以通过自己的业务需求内置的指令

注册
  • 局部注册
    new Vue({
      directives:{
            log:{
                inserted:function(el){
                    console.log(el);
                }
            }
        }
    })
    复制代码
  • 全局注册
    Vue.directive('focus',{
      inserted(el){
        el.focus()
      }
    })
    复制代码
directive选项

自定义指令通过几个钩子函数组成,每个钩子函数都是可选的。

  • bind
    • 只调用一次,指令第一次绑定到元素时调用,用此钩子函数可以定义一个绑定时执行一次的初始化动作。
  • inserted
    • 被绑定元素插入父节点时调用
  • update
    • 被绑定的元素所在的模板更新时调用,而不论绑定值是否变化,通过比较更新前后的绑定值,可以忽略不必要的模板更新
  • componentUpdated
    • 被绑定的元素再模板完成一次更新周期时调用
  • unbind
    • 只调用一次,指令与元素解绑时调用
钩子函数参数
  • el
    • 指令绑定的元素,可以用来直接操作dom
  • binding
    • name 指令名,不包括前缀
    • value 指令的绑定值
    • oldValue 指令绑定的前一个值,仅在updatecomponentUpdated钩子中可用
    • expression 绑定值的字符串形式
    • arg 传给指令的参数
    • modifiers 一个包含修饰符的对象。
  • vnode
    • Vue 编译生成的虚拟节点
  • oldVnode
    • 上一个虚拟节点,仅在updatecomponentUpdated钩子中可用

自定义组件的实践

<template>
    <div>
        <div class="main" v-clickoutside.esc='handleClose'>
            <button @click='show = !show'>点击我</button>
            <p v-show='show'>我是文字</p>
            <p v-show='show2' v-clickoutside='handleClose2'>我是文字2</p>
        </div>
    </div>
</template>

<script>

var nodeList = []; //存放需要响应的节点
var id = 0;//节点id
function handle(e){
  //遍历所有的节点
  nodeList.forEach(node=>{
    if(node.el.contains(e.target)){
      return false;
    }else{
      //如果当前点击的区域不是在节点上,执行函数
      //键盘响应esc键,当指令配置修饰符esc时,执行函数
      if(e.type != 'click' && !node.binding.modifiers.esc)return
      node.binding.value(e);
    }
  })
}
function keyDownEvent(e){
  //键盘响应函数
  if(e.keyCode == 27)handle(e);
}
document.addEventListener('click',handle);
document.addEventListener('keydown',keyDownEvent);
Vue.directive('clickoutside',{
  inserted(el,binding){
    el._id = id++;
    // 从nodeList中装载此节点。
    nodeList.push({
      id:el._id,
      el:el,
      binding:binding,
    })
  },
  unbind(el){
    // 从nodeList中卸载此节点。
    let len = nodeList.length;
    for (let i = 0; i < len; i++) {
      if(nodeList[i].id === el._id){
        nodeList.splice(i,1);
        break;
      }
    }
    delete el._id
  }
})

export default {
    data(){
        return{
            show:true,
            show2:true
        }
    },
    methods:{
        handleClose(){
            this.show = false
        },
        handleClose2(){
            this.show2 = false
        }
    }
}
</script>
复制代码
<template>
    <div>
        <span v-time='time'></span>
    </div>
</template>

<script>

var Time = {
  //获取当前的时间戳
  getUnix(){
    return new Date().getTime()
  },
  //获取当天零点时间戳
  getTodayUnix(){
    var date = new Date();
    date.setHours(0);
    date.setMinutes(0);
    date.setSeconds(0);
    date.setMilliseconds(0);
    return date.getTime();
  },
  //获取今年1月1日的时间戳
  getYearUnix(){
    var 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){
    var date = new Date(time);
    var month = date.getMonth() + 1 < 10 ? '0'+ (date.getMonth() + 1) :  date.getMonth() + 1;
    var day = date.setDate() < 10 ? '0'+ (date.setDate()) :  date.setDate();
    return date.getFullYear() + '-' + month + '-' + day;
  },
  //转换时间
  getFormatTime(timestamp){
    var now = this.getUnix();
    var today = this.getTodayUnix();
    var year = this.getYearUnix();
    var time = (now - timestamp) / 1000;
    var tip = '';
    if(time <= 0){
      tip = '刚刚';
    }else if(Math.floor(time / 60) <= 0){
      tip = '刚刚';
    }else if(time < 3600){
      tip = Math.floor(time/60) + '分钟前';
    }else if(time >= 3600 && (timestamp - today) >= 0){
      tip = Math.floor(time/3600) + '小时前';
    }else if(time/86400 <= 31){
      tip = Math.floor(time/86400) + '天前';
    }else{
      tip = this.getLastDate(timestamp);
    }
    return tip;
  }
}
Vue.directive('time',{
  bind(el,binding){
    el.innerHTML = Time.getFormatTime(binding.value);
  }
})
export default {
    data(){
        return{
            time: 1539669588000
        }
    }
}
</script>
复制代码

转载于:https://juejin.im/post/5bc53b4de51d450e597b9b25

相关文章:

  • AIX 系统 EBS form 打开报错FRM-92101: FORM server在启动过程中失败
  • JS面向对象编程
  • 解决Eclipse报errors running builder ‘javascript validator’ on project
  • 测试代码覆盖率工具学习(Android Emma)
  • c语言学习三
  • 微信群里的这些文章,都是谣言!赶紧给爸妈看看
  • 如何实现android蓝牙开发 自动配对连接,并不弹出提示框
  • JFreeChart绘制XY折线图(工具类设计)
  • ORACLE数据库笔记之PL/SQL
  • ByteTCC 0.5.0-ALPHA1 发布,基于 TCC 的分布式事务管理器
  • 马哥-51CTO-Linux培训-0901-linux文件系统
  • 【译】Cloudera Manager(CDH)入门系列之四 (管理员控制台)
  • 程序猿常识--OJ系统和ACM测试考试大全
  • linux-命令行快捷方式使用
  • mac 关闭dashboard 开机更快
  • [deviceone开发]-do_Webview的基本示例
  • Asm.js的简单介绍
  • IDEA常用插件整理
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • Laravel深入学习6 - 应用体系结构:解耦事件处理器
  • PHP那些事儿
  • Redux 中间件分析
  • SpringBoot几种定时任务的实现方式
  • vue2.0一起在懵逼的海洋里越陷越深(四)
  • 对JS继承的一点思考
  • 对象引论
  • 分享一份非常强势的Android面试题
  • 机器学习 vs. 深度学习
  • 人脸识别最新开发经验demo
  • 入口文件开始,分析Vue源码实现
  • 微信小程序开发问题汇总
  • 我建了一个叫Hello World的项目
  • 小程序 setData 学问多
  • 一文看透浏览器架构
  • 2017年360最后一道编程题
  • 我们雇佣了一只大猴子...
  • (173)FPGA约束:单周期时序分析或默认时序分析
  • (30)数组元素和与数字和的绝对差
  • (七)Knockout 创建自定义绑定
  • (原创) cocos2dx使用Curl连接网络(客户端)
  • (转)拼包函数及网络封包的异常处理(含代码)
  • ... 是什么 ?... 有什么用处?
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .NET Core 控制台程序读 appsettings.json 、注依赖、配日志、设 IOptions
  • .net Stream篇(六)
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .NET/C# 使用 #if 和 Conditional 特性来按条件编译代码的不同原理和适用场景
  • .net反混淆脱壳工具de4dot的使用
  • .NET开发者必备的11款免费工具
  • @KafkaListener注解详解(一)| 常用参数详解
  • [ C++ ] STL---stack与queue
  • [ 蓝桥杯Web真题 ]-Markdown 文档解析
  • [2013][note]通过石墨烯调谐用于开关、传感的动态可重构Fano超——
  • [2016.7 test.5] T1
  • [AMQP Connection 127.0.0.1:5672] An unexpected connection driver error occured