Vue自定义指令的使用,具体内容如下

1.自定义指令的语法

Vue自定义指令语法如下:

  1. Vue.directive(id, definition)

传入的两个参数,id是指指令ID,definition是指定义对象。其中,定义对象可以提供一些钩子函数

钩子函数

一个指令定义对象可以提供如下几个钩子函数 (均为可选):

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。

我们会在稍后讨论渲染函数时介绍更多 VNodes 的细节。

  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

  • unbind:只调用一次,指令与元素解绑时调用。

接下来我们来看一下钩子函数的参数 (即 elbindingvnode 和 oldVnode)。

钩子函数参数

指令钩子函数会被传入以下参数:

  • el:指令所绑定的元素,可以用来直接操作 DOM 。
  • binding:一个对象,包含以下属性:vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
    • 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 }
  • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。

这是一个使用了这些属性的自定义钩子样例:

  1. Vue.directive('my-directive', {
  2. bind: function(){
  3. //做绑定的准备工作
  4. //比如添加事件监听器,或是其他只需要执行一次的复杂操作
  5. },
  6. inserted: function(){
  7. //...
  8. },
  9. update: function(){
  10. //根据获得的新值执行对应的更新
  11. //对于初始值也会调用一次
  12. },
  13. componentUpdated: function(){
  14. //...
  15. },
  16. unbind: function(){
  17. //做清理操作
  18. //比如移除bind时绑定的事件监听器
  19. }

官网文档:https://cn.vuejs.org/v2/guide/custom-directive.html

使用场景

  • 代码复用和抽象的主要形式是组件
  • 当需要对普通 DOM 元素进行底层操作,此时就会用到自定义指令
  • 但是,对于大幅度的 DOM 变动,还是应该使用组件

3. 示例

3.1 输入框自动聚焦

  1. // 注册一个全局自定义指令 `v-focus`
  2. Vue.directive('focus', {
  3. // 当被绑定的元素插入到 DOM 中时
  4. inserted: function (el) {
  5. // 聚焦元素
  6. el.focus()
  7. }
  8. })
  9. <input v-focus>

3.2 下拉菜单

  • 点击下拉菜单本身不会隐藏菜单
  • 点击下拉菜单以外的区域隐藏菜单
  1. Vue.directive('clickoutside', {
  2. bind(el, binding) {
  3. function documentHandler(e) {
  4. if (el.contains(e.target)) {
  5. return false
  6. }
  7.  
  8. if (binding.expression) {
  9. binding.value(e)
  10. }
  11. }
  12.  
  13. el.__vueMenuHandler__ = documentHandler
  14. document.addEventListener('click', el.__vueMenuHandler__)
  15. },
  16. unbind(el) {
  17. document.removeEventListener('click', el.__vueMenuHandler__)
  18. delete el.__vueMenuHandler__
  19. }
  20. })
  21.  
  22. new Vue({
  23. el: '#app',
  24. data: {
  25. show: false
  26. },
  27. methods: {
  28. handleHide() {
  29. this.show = false
  30. }
  31. }
  32. })
  1. <div class="main" v-menu="handleHide">
  2. <button @click="show = !show">点击显示下拉菜单</button>
  3. <div class="dropdown" v-show="show">
  4. <div class="item"><a href="#">选项 1</a></div>
  5. <div class="item"><a href="#">选项 2</a></div>
  6. <div class="item"><a href="#">选项 3</a></div>
  7. </div>
  8. </div>

3.3 相对时间转换

类似微博、朋友圈发布动态后的相对时间,比如刚刚、两分钟前等等

  1. <span v-relativeTime="time"></span>
  2. new Vue({
  3. el: '#app',
  4. data: {
  5. time: 1565753400000
  6. }
  7. })
  8.  
  9. Vue.directive('relativeTime', {
  10. bind(el, binding) {
  11. // Time.getFormatTime() 方法,自行补充
  12. el.innerHTML = Time.getFormatTime(binding.value)
  13. el.__timeout__ = setInterval(() => {
  14. el.innerHTML = Time.getFormatTime(binding.value)
  15. }, 6000)
  16. },
  17. unbind(el) {
  18. clearInterval(el.innerHTML)
  19. delete el.__timeout__
  20. }
  21. })

3.4 滚动动画

  1. <div id="app">
  2. <h1 class="centered">Scroll me</h1>
  3. <div class="box" v-scroll="handleScroll">
  4. <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. A atque amet harum aut ab veritatis earum porro praesentium ut corporis. Quasi provident dolorem officia iure fugiat, eius mollitia sequi quisquam.</p>
  5. </div>
  6. </div>
  1. Vue.directive('scroll', {
  2. inserted: function(el, binding) {
  3. let f = function(evt) {
  4. if (binding.value(evt, el)) {
  5. window.removeEventListener('scroll', f)
  6. }
  7. }
  8. window.addEventListener('scroll', f)
  9. }
  10. })
  11.  
  12. // main app
  13. new Vue({
  14. el: '#app',
  15. methods: {
  16. handleScroll: function(evt, el) {
  17. if (window.scrollY > 50) {
  18. TweenMax.to(el, 1.5, {
  19. y: -10,
  20. opacity: 1,
  21. ease: Sine.easeOut
  22. })
  23. }
  24. return window.scrollY > 100
  25. }
  26. }
  27. })
  1. body {
  2. font-family: 'Abhaya Libre', Times, serif;
  3. -webkit-font-smoothing: antialiased;
  4. -moz-osx-font-smoothing: grayscale;
  5. background: #000;
  6. color: #fff;
  7. overflow-x: hidden;
  8. }
  9.  
  10. h1,
  11. h2,
  12. h3,
  13. h4 {
  14. font-family: 'Fira Sans', Helvetica, Arial, sans-serif;
  15. font-weight:;
  16. }
  17.  
  18. .centered {
  19. margin: 0 auto;
  20. display: table;
  21. font-size: 60px;
  22. margin-top: 100px;
  23. }
  24.  
  25. .box {
  26. border: 1px solid rgba(255, 255, 255, 0.5);
  27. padding: 8px 20px;
  28. line-height: 1.3em;
  29. opacity:;
  30. color: white;
  31. width: 200px;
  32. margin: 0 auto;
  33. margin-top: 30px;
  34. transform: translateZ(0);
  35. perspective: 1000px;
  36. backface-visibility: hidden;
  37. background: rgba(255, 255, 255, 0.1);
  38. }
  39.  
  40. #app {
  41. height: 2000px;
  42. }

自定义指令:
属性:

Vue.directive(指令名称,function(参数){
this.el -> 原生DOM元素
});

<div v-red="参数"></div>

指令名称: v-red -> red

* 注意: 必须以 v-开头

拖拽:
-------------------------------
自定义元素指令:(用处不大)
Vue.elementDirective('zns-red',{
bind:function(){
this.el.style.background='red';
}
});
------------------------------------------------
@keydown.up
@keydown.enter

@keydown.a/b/c....

自定义键盘信息:
Vue.directive('on').keyCodes.ctrl=17;
Vue.directive('on').keyCodes.myenter=13;
------------------------------------------------

Vue自定义指令使用方法详解 和 使用场景的更多相关文章

  1. Vue入门---事件与方法详解

    一. vue方法实现 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> &l ...

  2. join() 方法详解及应用场景

    总结:join方法的功能就是使异步执行的线程变成同步执行.也就是说,当调用线程实例的start方法后,这个方法会立即返回,如果在调用start方法后后需要使用一个由这个线程计算得到的值,就必须使用jo ...

  3. 每个人都能实现的vue自定义指令

    前文 先来bb一堆废话哈哈.. 用vue做项目也有一年多了.除了用别人的插件之外.自己也没尝试去封装指令插件之类的东西来用. 刚好最近在项目中遇到一个问题.(快速点击按钮多次触发多次绑定的方法),于是 ...

  4. vue自定义指令,比onerror更优雅的方式实现当图片加载失败时使用默认图,提供三种方法

    首先,来看下效果图(演示一下图片正常加载与加载失败时的效果) 在线体验地址:https://hxkj.vip/demo/vueImgOnerror/ 一.常规方法解决 我们都知道,img标签支持one ...

  5. vue自定义指令

    Vue自定义指令: Vue.directive('myDr', function (el, binding) { el.onclick =function(){ binding.value(); } ...

  6. Vue插件编写、用法详解(附demo)

    Vue插件编写.用法详解(附demo) 1.概述 简单来说,插件就是指对Vue的功能的增强或补充. 比如说,让你在每个单页面的组件里,都可以调用某个方法,或者共享使用某个变量,或者在某个方法之前执行一 ...

  7. AngularJS指令进阶 – ngModelController详解

    AngularJS指令进阶 – ngModelController详解 在自定义Angular指令时,其中有一个叫做require的字段,这个字段的作用是用于指令之间的相互交流.举个简单的例子,假如我 ...

  8. Vue自定义指令使用场景

    当你第一次接触vue的时候,一定会使用到其中的几个指令,比如:v-if.v-for.v-bind...这些都是vue为我们写好的,用起来相当的爽.如果有些场景不满足,需要我们自己去自定义,那要怎么办呢 ...

  9. 使用Vue自定义指令实现Select组件

    完成的效果图如下: 一.首先,我们简单布局一下: <template> <div class="select"> <div class="i ...

随机推荐

  1. Nginx 简介与安装、常用的命令和配置文件

    1.nginx 简介(1)介绍 nginx 的应用场景和具体可以做什么事情 (2)介绍什么是反向代理 (3)介绍什么是负载均衡 (4)介绍什么是动静分离 2.nginx 安装(1)介绍 nginx 在 ...

  2. Spring学习的第二天

    第二天总共学习了以下内容: spring中的ioc常用注解: 案例使用xml方式和注解方式实现单表的CRUD操作(但还是需要xml配置文件,并不是纯注解的配置): 改造基于注解的Ioc案例,使用纯注解 ...

  3. 用python暴力破解压缩文件并不是万能,至少这个场景我告诉你密码你用代码也破解不了

    看到论坛上各种贴子写用python进行暴力破解的文章,于是自己也想去尝试一下,不试不知道,一试吓一跳,真的就像那句有名的”python由入门到放弃“,把论坛上别人的脚本全部自己敲一遍,运行不报错,但也 ...

  4. 剑指Offer-40.数组中只出现一次的数字(C++/Java)

    题目: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 分析: 我们知道,两个相同的数字异或的结果等于0,所以利用这个性质将数组中所有的数字异或,求得的结 ...

  5. E-factory

    E-factory为生成XML和HTML提供了一种简单而紧凑的语法 # coding:utf-8 from lxml.builder import E def CLASS(*args): # clas ...

  6. c++实现通讯录管理系统(控制台版)

    c++实现通讯录管理系统(控制台版) 此项目适合c++初学者,针对c++基础知识,涉及到变量.结构体定义使用.数组定义使用.指针定义使用等. 运行之后的结果如下: 代码: #include <i ...

  7. Spring Cloud Gateway、并发编程等等

    2019年 JUC线程池服务ExecutorService接口实现源码分析 Github Page:http://www.throwable.club/2019/07/27/java-concurre ...

  8. Redis Cluster 集群三主三从高可用环境搭建

    前言 Redis 是我们目前大规模使用的缓存中间件,由于它强大高效而又便捷的功能,得到了广泛的使用. Window环境下载地址:https://github.com/tporadowski/redis ...

  9. Linux ssh突然连接不了的案例浅析

    公司的Linux服务器都是通过一台JumpServer跳转的.个人使用Jumpserver(开源跳板机系统)时,有时候由于需要上传.下载文件很不方便.而由于配置关系,一般情况无法使用SecureCRT ...

  10. tomcat修改进程名称

    1.window平台: 打开tomcat_home\bin\setclasspath.bat文件,找到set _RUNJAVA=”%JRE_HOME%\bin\java”这一行. 将该行注释掉 ,然后 ...