zoukankan      html  css  js  c++  java
  • Vue自定义指令使用方法详解 和 使用场景

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

    1.自定义指令的语法

    Vue自定义指令语法如下:

    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 来进行。

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

    Vue.directive('my-directive', {
     bind: function(){
     //做绑定的准备工作
     //比如添加事件监听器,或是其他只需要执行一次的复杂操作
     },
     inserted: function(){
     //...
     },
     update: function(){
     //根据获得的新值执行对应的更新
     //对于初始值也会调用一次
     },
     componentUpdated: function(){
     //...
     },
     unbind: function(){
     //做清理操作
     //比如移除bind时绑定的事件监听器
     }

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

    使用场景

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

    3. 示例

    3.1 输入框自动聚焦

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

    3.2 下拉菜单

    • 点击下拉菜单本身不会隐藏菜单
    • 点击下拉菜单以外的区域隐藏菜单
    Vue.directive('clickoutside', {
      bind(el, binding) {
        function documentHandler(e) {
          if (el.contains(e.target)) {
           return false 
          }
          
          if (binding.expression) {
            binding.value(e)
          }
        }
        
        el.__vueMenuHandler__ = documentHandler
        document.addEventListener('click', el.__vueMenuHandler__)
      },
      unbind(el) {
        document.removeEventListener('click', el.__vueMenuHandler__)
        delete el.__vueMenuHandler__
      }
    })
    
    new Vue({
      el: '#app',
      data: {
        show: false
      },
      methods: {
        handleHide() {
          this.show = false
        }
      }
    })
    <div class="main" v-menu="handleHide">
      <button @click="show = !show">点击显示下拉菜单</button>
      <div class="dropdown" v-show="show">
        <div class="item"><a href="#">选项 1</a></div>
        <div class="item"><a href="#">选项 2</a></div>
        <div class="item"><a href="#">选项 3</a></div>
      </div>
    </div>

    3.3 相对时间转换

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

    <span v-relativeTime="time"></span>
    new Vue({
      el: '#app',
      data: {
        time: 1565753400000
      }
    })
    
    Vue.directive('relativeTime', {
      bind(el, binding) {
        // Time.getFormatTime() 方法,自行补充
        el.innerHTML = Time.getFormatTime(binding.value)
        el.__timeout__ = setInterval(() => {
          el.innerHTML = Time.getFormatTime(binding.value)
        }, 6000)
      },
      unbind(el) {
        clearInterval(el.innerHTML)
        delete el.__timeout__
      }
    })

    3.4 滚动动画

    <div id="app">
      <h1 class="centered">Scroll me</h1>
      <div class="box" v-scroll="handleScroll">
        <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>
      </div>
    </div>
    Vue.directive('scroll', {
      inserted: function(el, binding) {
        let f = function(evt) {
          if (binding.value(evt, el)) {
            window.removeEventListener('scroll', f)
          }
        }
        window.addEventListener('scroll', f)
      }
    })
    
    // main app
    new Vue({
      el: '#app',
      methods: {
       handleScroll: function(evt, el) {
        if (window.scrollY > 50) {
          TweenMax.to(el, 1.5, {
            y: -10,
            opacity: 1,
            ease: Sine.easeOut
          })
        }
        return window.scrollY > 100
        }
      }
    })
    body {
      font-family: 'Abhaya Libre', Times, serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      background: #000;
      color: #fff;
      overflow-x: hidden;
    }
    
    h1,
    h2,
    h3,
    h4 {
      font-family: 'Fira Sans', Helvetica, Arial, sans-serif;
      font-weight: 800;
    }
    
    .centered {
      margin: 0 auto;
      display: table;
      font-size: 60px;
      margin-top: 100px;
    }
    
    .box {
      border: 1px solid rgba(255, 255, 255, 0.5);
      padding: 8px 20px;
      line-height: 1.3em;
      opacity: 0;
      color: white;
      width: 200px;
      margin: 0 auto;
      margin-top: 30px;
      transform: translateZ(0);
      perspective: 1000px;
      backface-visibility: hidden;
      background: rgba(255, 255, 255, 0.1);
    }
    
    #app {
      height: 2000px;
    }


    自定义指令:
    属性:

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

  • 相关阅读:
    Android客户端与服务器交互方式-小结
    个人工作总结01
    第7周学习进度
    第6周学习进度
    PHP_D4_“简易聊天室 ”的具体技术实现
    php_D3_“简易聊天室 ”实现的关键技术 详解
    团队介绍
    最大联通子数组
    构建之法阅读笔记04
    大道至简阅读笔记04
  • 原文地址:https://www.cnblogs.com/lguow/p/11937807.html
Copyright © 2011-2022 走看看