WD1X.COM - 问答一下,轻松解决,电脑应用解决专家
主板显卡CPU内存显示器
硬盘维修显卡维修显示器维修
注册表系统命令DOS命令Win8
存储光存储鼠标键盘
内存维修打印机维修
WinXPWin7Win11Linux
硬件综合机箱电源散热器手机数码
主板维修CPU维修键盘鼠标维修
Word教程Excel教程PowerPointWPS
网络工具系统工具图像工具
数据库javascript服务器
PHP教程CSS教程XML教程

探索vue自定义指令的玄妙

更新时间:2021-06-23 14:44 作者:恪愚点击:
自定义指令的语法
Vue自定义指令语法如下:
 
Vue.directive(id, definition)
 
传入的两个参数,id是指指令ID,definition是指定义对象。其中,定义对象可以提供一些钩子函数:
 
钩子函数
定义对象的钩子函数如下:
 
bind:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作
inserted:被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于document中)
update:被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新
componentUpdate:被绑定元素所在模板完成一次更新周期时调用
unbind:只调用一次,指令与元素解绑时使用
在钩子函数中,还有一些参数可供选择:
 
参数 描述
el 指令所绑定的元素,可以直接操作Dom
binding 指令的描述对象
arg 传给指令的参数,可选。例如 v-transfer:f40="{id:item.id,name:'mxc'}",在指令中可通过:binding.value.id/name 获取(这时 arg 就是 f40 )
vnode Vue 编译生成的虚拟节点
oldVnode 上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用
而在binding中,还有几个属性:
 
name: 指令名,不包括v- 前缀
value: 指令的绑定值。例如: v-my-directive=”1 + 1”,value 的值是 2。
oldValue: 指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 “1 + 1”
简单使用
Vue自定义指令常见使用例子如下:
 
Vue.directive('my-directive', {
    bind: function(){
        //做绑定的准备工作
        //比如添加事件监听器,或是其他只需要执行一次的复杂操作
    },
    inserted: function(){
        //...
    },
    update: function(){
        //根据获得的新值执行对应的更新
        //对于初始值也会调用一次
    },
    componentUpdated: function(){
        //...
    },
    unbind: function(){
        //做清理操作
        //比如移除bind时绑定的事件监听器
    }
}
 
当指令的定义对象中只使用update时,只需直接传入函数即可,如下:
 
//全局方式
Vue.directive('my-directive', function(){
    //...
})
//局部的方式下面的例子就是
 
自定义指令是怎么和methods关联起来的
像简单的一些自定义指令比如赋值甚至内置的v-focus来说,使用非常方便,直接在回调中操作即可。
但是如果让你使用自定义指令实现拖拽、触底校验…这类复杂的操作呢?
 
这是完全有可能的。因为自定义指令的特殊性,我们完全可以用自定义指令做一些小的插件。而插件不可能涵盖所有的场景。
 
这时候就需要methods中函数(通过v-on,即@注册的)的参与了!
实际上,vue中是通过传参的形式,将methods中的函数传进来,以此来改变data中的值。就像这样:
 
methods:{
    set(x,y){
        this.data.x=x;
this.data.y=y;
}
},
 
directives:{
// 拖动的自定义指令
drag(el,binding){
//el为拖动的元素
var oDiv =el;
  oDiv.onmousedown = function(e){
  e.preventDefault();
      e.stopPropagation();
  var disX = e.offsetX;
  var disY = e.offsetY;
  document.onmousemove = function(e){
  e.preventDefault();
e.stopPropagation();
  var x=e.pageX-disX;
  var y=e.pageY-disY
    oDiv.style.left=x
oDiv.style.top=y
  // 通过传参的形式,将methods中的函数传进来,以此来改变data中的值
  binding.value.set(x,y)
  };
  document.onmouseup = function(){
  document.onmousemove=null;
  document.onmouseup=null;
  };
  };
}
},
 
然后使用:
 
<div v-drag="{set:set}"></div>
 
指令的生命周期?
指令本质上是一个JavaScript对象,对象上挂载着一些钩子函数。
我们可以举个例子来说明:比如笔者定义一个v-log指令,这个指令做的事情就是在指令的各个生命周期中去输出一些log信息:
 
const logDirective = {
  beforeMount() {
    console.log('log directive before mount')
  },
  mounted() {
    console.log('log directive mounted')
  },
  beforeUpdate() {
    console.log('log directive before update')
  },
  updated() {
    console.log('log directive updated')
  },
  beforeUnmount() {
    console.log('log directive beforeUnmount')
  },
  unmounted() {
    console.log('log directive unmounted')
  }
}
 
然后你可以以全局指令 方式在创建应用后注册它:
 
import { createApp } from 'vue';
import App from './App';
const app=createApp(App);
app.directive('log',logDirective);
app.mount('#app');
 
使用上也很方便:
 
<template>
    <input v-if="flag" v-log v-model="text"/>
    <button @click="flag=!flag">toggle</button>
</template>
<script>
export default {
    data() {
        return {
          flag: true,
            text: ''
        }
    }
}
</script>
 
当你点击按钮后,会先执行指令定义的 beforeMount 和 mounted 钩子函数,然后你在 input 输入框中输入一些内容,会执行 beforeUpdate 和 updated 钩子函数,然后你再次点击按钮,会执行 beforeUnmount 和 unmounted 钩子函数。
 
所以一个指令的定义,无非就是在合适的钩子函数中编写一些相关的处理逻辑。
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
你可能感兴趣的内容