写点什么

vue 自定义指令

用户头像
法医
关注
发布于: 3 小时前
vue自定义指令

我想大家都接触过 v-on、v-show 等等指令,那自定义指令是什么呢?自定义指令就是你现在所想的那样,自己写一个自定义指令去操作 DOM 元素,以达到代码复用的目的。一提到代码复用,我想大家都能想到组件,这里要注意的是自定义指令组件的适用范围是不一样的。组件一般是我们复用一个结构、一个样式、一个逻辑。而自定义指令是当我们想对 dom 进行底层操作,而且底层操作是一样功能的时候,这时就可以使用自定义指令了。


注册指令分为全局注册局部注册


全局注册


Vue.directive('focus', {/** */})
复制代码


局部注册


const vm = new Vue({  el: '#app',  directives: {    focus: {/** */}  }})
复制代码


例:写一个自动聚焦输入框的指令 v-focus


<body>  <div id="app">    <input type="text" v-focus>  </div>
<script> //定义全局指令 Vue.directive("focus",{ inserted(el){ el.focus() } }) //定义局部指定 const vm = new Vue({ el: "#app", data: {}, directives: { focus: { inserted(el) { el.focus(); }, }, }, </script></body>
复制代码


但凡有 input 框需要自动聚焦,直接加上v-focus就可以了。


注意:当全局指令和局部指令名字冲突的时候,会使用局部指令,所以在自定义指令的时候,要么全局,要么局部,二选一。


实现结果:


自定义指令生命周期钩子函数

接下来详细说明自定义指令配置对象,配置对象里面的东西并没有那么难,都是一些钩子函数,执行到某些时刻就执行的函数,也可以叫自定义指令生命周期钩子函数。


  • bind


当把指令绑定到 dom 元素身上的时候就会执行,由于只绑定一次,所以只执行一次,在这里可以进行一次性的初始化设置。


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

  • update 所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。

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

  • unbind 指令与 dom 元素解绑时调用(被绑定的 Dom 元素被 Vue 移除),只调用一次。

钩子函数的参数

  • el:指令所绑定的元素,可以用来直接操作 DOM

  • binding:对象,包含以下属性:

  • name : 指令名,不包括 v-前缀

  • value :指令的绑定值,例如:v-focus="1+1"中,绑定值为 2.

  • oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可以使用。

  • expression:字符串形式的指令表达式。例如,v-focus="1+1",表达式为"1+1"

  • arg : 传给指令的参数,可选。例如,v-focus:src 中,参数为"src"

  • modifiers:一个包含修饰符的对象。例如,v-focus.obj.nice 中,修饰符对象为{obj: true, nice: true}

  • vnode:Vue 编译生成的虚拟节点。

  • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用

模拟 v-show 指令

<body>    <div id="app">      <input type="text" v-myshow="show" />    </div>
<script> //模拟show指令 Vue.directive("myshow", { bind(el, binding) { const { value } = binding; const display = value ? "" : "none"; el.style.display = display; }, update(el,binding) { const { value } = binding; const display = value ? "" :"none"; el.style.display = display; }, });
const vm = new Vue({ el: "#app", data: { show: true, }, }); </script> </body>
复制代码


结果演示:



如果在 bind 和 update 中触发相同的行为,而不关心其它钩子函数时,可以写成函数的形式,如下:


<body>    <div id="app">      <input type="text" v-myshow="show" />    </div>
<script> //模拟show指令 Vue.directive("myshow",(el,binding)=>{ const { value } = binding; const display = value ? "" : "none"; el.style.display = display; });

const vm = new Vue({ el: "#app", data: { show: true, }, }); </script> </body>
复制代码

模拟 v-modle 指令

 <body>    <div id="app">      <input type="text" v-mymodel="content" />{{ content }}    </div>
<script> //模拟v-model指令 Vue.directive("mymodel",{ bind(el,binding,vnode){ const vm= vnode.context; const {value,expression} = binding; el.value = binding.value el.oninput = function(){ const inputValue = el.value; vm[expression] = inputValue; } }, update(el,binding){ const {value} = binding; el.value = value } })
const vm = new Vue({ el: "#app", data: { content:"法医" }, }); </script> </body>
复制代码


结果演示:



发布于: 3 小时前阅读数: 2
用户头像

法医

关注

公众号@前端猎手 2020.07.17 加入

喜欢用写作记录自己技术成长过程

评论

发布
暂无评论
vue自定义指令