使用vue directive 创建一个loading指令

36 阅读2分钟

效果

image.png

时间点

  • 触发: created 网络请求响应前显示,isLoading:true
  • 销毁:网络请求成功销毁,isloading:false

为什么使用directive

loading 使用的场景非常多, 如果以组件的形式使用,每次都要导入和注册,非常麻烦,因此使用 vue 指令可以随时创建指令生成loading

directive

全局定义

// 指令名称为:mydirec1
Vue.directive('mydirec1', {
  // 指令配置
})

// 指令名称为:mydirec2
Vue.directive('mydirec2', {
  // 指令配置
})

之后,所有的组件均可以使用 mydirec1mydirec2指令

<template>
  <!-- 某个组件代码 -->
  <div>
    <MyComp v-mydirec1="js表达式" />
    <div v-mydirec2="js表达式">
      ...
    </div>
    <img v-mydirec1="js表达式" />
  </div>
</template>

局部定义

局部定义是指在某个组件中定义指令,和局部注册组件类似。

定义的指令仅在该组件中有效。

<template>
  <!-- 某个组件代码 -->
  <div>
    <MyComp v-mydirec1="js表达式" />
    <div v-mydirec2="js表达式">
      ...
    </div>
    <img v-mydirec1="js表达式" />
  </div>
</template>

<script>
export default {
  // 定义指令
  directives: {
    // 指令名称:mydirec1
    mydirec1: {
      // 指令配置
    },
    // 指令名称:mydirec2
    mydirec2: {
      // 指令配置
    }
  }
}
</script>

和局部注册组件一样,为了让指令更加通用,通常我们会把指令的配置提取到其他模块。

<template>
  <!-- 某个组件代码 -->
  <div>
    <MyComp v-mydirec1="js表达式" />
    <div v-mydirec2="js表达式">
      ...
    </div>
    <img v-mydirec1="js表达式" />
  </div>
</template>

<script>
  // 导入当前组件需要用到的指令配置对象
  import mydirec1 from "@/directives/mydirec1";
  import mydirec2 from "@/directives/mydirec2";
	export default {
    // 定义指令
    directives: {
      mydirec1,
      mydirec2
    }
  }
</script>

指令配置对象

没有配置的指令,就像没有配置的组件一样,毫无意vue支持在指令中配置一些钩子函数,在适当的时机,vue会调用这些钩子函数并传入适当的参数,以便开发者完成自己想做的事情。

常用的钩子函数:

// 指令配置对象
{
  bind(){
    // 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  },
  inserted(){
    // 被绑定元素插入父节点时调用。
  },
  update(){
    // 所在组件的 VNode 更新时调用
  }
}

查看更多的钩子函数

每个钩子函数在调用时,vue都会向其传递一些参数,其中最重要的是前两个参数

// 指令配置对象
{
  bind(el, binding){
    // el 是被绑定元素对应的真实DOM
    // binding 是一个对象,描述了指令中提供的信息
  }
}

bingding 对象

image-20210104174229660

查看更多bingding对象的属性

配置简化

比较多的时候,在配置自定义指令时,我们都会配置两个钩子函数

{
  bind(el, bingding){
  
  },
  update(el, bingding){
  
  }
}

这样,在元素绑定和更新时,都能运行到钩子函数

如果这两个钩子函数实现的功能相同,可以直接把指令配置简化为一个单独的函数:

function(el, bingding){
  // 该函数会被同时设置到bind和update中
}

更多的自定义指令用法见官网

demo loading 指令

初始化

  • src/directives 目录
  • loading目录
  • 注册loading 指令
  • 指令配置
import vLoading from "./directives/loading/loading.js";
Vue.directive("loading", vLoading);
// 注册指令,传入配置对象

指令接受来自el 的value,判断是否生成,true生成,false销毁

image.png