Vue从甜小白到皮大佬系列(四) 自定义指令

3,377 阅读5分钟

🎉 Vue构建大型单页面电商应用 开源啦!点我看源码🚀🚀

阅读时间预估:3分钟

啥是指令?

Vue从甜小白到皮大佬系列(二) v-指令

指令的钩子函数参数

啥是自定义指令?

在前端开发领域,以前的通用框架是jQuery,jQuery以及基于jQuery构建的通用组件形成了一个庞大的生产系统。现在的通用框架是Angular、React和Vue,每个框架都需要基于自身构建新的组件库,自定义指令好就好在:原先的那些通用组件,无论是纯js的也好,基于jQuery的也好,都可以拿来主义直接吸收,而不需要改造或重构,自定义指令可以很方便的将大量重复的事情通过一个简短的指令来实现.

  • 作用:进行DOM操作
  • 使用场景:对纯 DOM 元素进行底层操作,比如:文本框获得焦点
  • 两种指令:1 全局指令 2 局部指令

自定义全局指令

  • 作用:定义一个指令可以全局通用
  • 关键code: Vue.directive()
  • 建议:最好是单独创建一个文件然后引入到main.js文件中单独管理
// 第一个参数:指令名称
// 第二个参数:配置对象,指定指令的钩子函数
Vue.directive('directiveName', {
    // bind中只能对元素自身进行DOM操作,而无法对父级元素操作
    // 只调用一次 指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  bind( el,binding, vnode ) {
      // 参数详解
      // el:指令所绑定的元素,可以用来直接操作 DOM 。
      // binding:一个对象,包含以下属性:
      // name:指令名,不包括 v- 前缀。
      // value:指令的绑定值,等号后面的值 。
      // oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
      // expression:字符串形式的指令表达式 等号后面的字符串 形式
      // arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。
      // modifiers:指令修饰符。例如:v-directive.foo.bar中,修饰符对象为 { foo: true, bar: true }。
      // vnode:Vue 编译生成的虚拟节点。。
      // oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
  },
  
  // inserted这个钩子函数调用的时候,当前元素已经插入页面中了,也就是说可以获取到父级节点了
  inserted (  el,binding, vnode ) {},
  //  DOM重新渲染前
  update(el,binding, vnode,oldVnode) {},
  // DOM重新渲染后
  componentUpdated ( el,binding, vnode,oldVnode ) {},
  // 只调用一次,指令与元素解绑时调用
  unbind ( el ) {
    // 指令所在的元素在页面中消失,触发
  }
})
// 简写 如果你想在 bind 和 update 时触发相同行为,而不关心其它的钩子:
Vue.directive('自定义指令名', function( el, binding ) {})
// 例:
Vue.directive('color', function(el, binding) {
  el.style.color = binging.value
})
// 使用 注意直接些会被i成data中的数据“red” 需要字符串则嵌套引号"'red'"
<p v-color="'red'"></p>

※建议用如下方法来组织全局组件

  • 1.首先创建一个directive.js文件然后编写全局的自定义组件.例如我想定义一个直接修改Dom颜色和文字大小的自定义组件
export default (Vue) => {
    Vue.directive('dColor', {
        inserted: function (el, binding) {
            el.style.color = binding.value;
        }
    });
    Vue.directive('dFont', {
        inserted: function (el, binding) {
            el.style.fontSize = binding.value + "px";
        }
    });
}
  • 2.在main.js文件中引入directive.js文件,并使用Vue.use(directive)调用她
import Vue from 'vue';
import App from './App.vue';
import directive from './directive';

Vue.config.productionTip = false;

Vue.use(directive); //全局使用directive文件

new Vue({
    render: h => h(App),
}).$mount('#app')

  • 3.在你想使用的地方直接调用你定义好的组件名,一定要加v-哦!
<template>
    <div class="hello">
        <p v-dColor="'red'"> 我是全局定义的组件修改颜色值</p>
        <p v-dFont="'50'"> 我是全局定义的组件可以修改大小</p>
    </div>
</template>

自定义局部指令

  • 作用:定义一个指令,只能局部组件使用
  • 使用场景:组件中经常重用的某些操作Dom的方法,仅在在这一个组件中使用
  • 关键code钩子: directives: 写一个局部指令,定义一个input自动焦点的指令
<script>
export default {
    name: 'HelloWorld',
    props: {
        msg: String
    },
    directives: {
        // 自定义组件的名字
        autoFocus: {
            // 钩子函数,被绑定元素插入父节点时调用 (父节点存在即可调用,不必存在于 document 中)。
            inserted (el) {
                el.focus();
                console.log('inserted');
            },
            // 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
            bind () {
                console.log('bind');
            },
            // 所在组件的 VNode 更新时调用,但是可能发生在其孩子的 VNode 更新之前。
            // 指令的值可能发生了改变也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 
            updata () {
                console.log('updata');
            },
            // 所在组件的 VNode 及其孩子的 VNode 全部更新时调用。
            componentUpdated () {
                console.log('componentUpdated');
            },
            // 只调用一次,指令与元素解绑时调用。
            unbind () {
                console.log('unbind');
            }
        }
    }
}
</script>

4.在需要使用的地方调用v-autoFocus直接使用

<template>
    <div class="hello">
        <p v-dColor="'red'"> 我是全局定义的组件修改颜色值</p>
        <p v-dFont="'50'"> 我是全局定义的组件可以修改大小</p>
        <input type="text"
               placeholder="请输入文字"
               v-autoFocus>
    </div>
</template>

看完这篇不知道面前的这位大侠是否真正学会了自定义指令,自己动手写一个全局的指令以及局部指令,全局指令一定要单独放一个文件夹中管理哦😆加油,前端甜小白....

如果我的分享对面前的这位大侠有所启发,不要吝啬以程序员最高礼遇点赞✨ 评论加分享的方式鼓励我.

关注公众号回复:学习 领取前端最新最全学习资料,也可以进群和大佬一起学习交流.

猛戳 我的前端进阶Blog