自学内容网 自学内容网

vue自定义指令

自定义指令

一个自定义指令由一个包含类似组件生命周期钩子的对象来定义。钩子函数会接收到指令所绑定元素作为其参数

如同生命周期钩子一样,都需要三个主要参数来进行,如下:

const myDirective = {
  // 在绑定元素的 attribute 前
  // 或事件监听器应用前调用
  created(el, binding, vnode) {
    // 下面会介绍各个参数的细节
  },
  // 在元素被插入到 DOM 前调用
  beforeMount(el, binding, vnode) {},
  // 在绑定元素的父组件
  // 及他自己的所有子节点都挂载完成后调用
  mounted(el, binding, vnode) {}
}

参数

一一介绍钩子的参数:

el:

指令绑定到的元素。这可以用于直接操作 DOM。

binding:

一个对象,包含以下属性:

  • value:传递给指令的值。例如在 v-my-directive="1 + 1" 中,传递的值是 2
  • oldValue:之前的值,仅在 beforeUpdateupdated 中可用。无论值是否更改,它都可用。
  • arg:传递给指令的参数 (如果有的话)。例如在 v-my-directive:foo 中,参数是 "foo"
  • modifiers:一个包含修饰符的对象 (如果有的话)。例如在 v-my-directive.foo.bar 中,修饰符对象是 { foo: true, bar: true }
  • instance:使用该指令的组件实例。
  • dir:指令的定义对象。

vnode:

代表绑定元素的底层 VNode。

prevvnode:

代表之前的渲染中指令所绑定元素的 VNode。仅在 beforeUpdateupdated 钩子中可用。

参数配置方法

配置指令对象

// 指令配置对象
{
    // 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  bind(el, binding){
    // el 是被绑定元素对应的真实DOM
    // binding 是一个对象,描述了指令中提供的信息
  },
  inserted(){
    // 被绑定元素插入父节点时调用。
  },
  update(){
    // 所在组件的 VNode 更新时调用
  }
}

配置指令函数

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

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

全局注册

第一个参数为名字,如下,调用则使用v-loading

第二个参数为指令参数配置对象

// 注册全局自定义指令
Vue.directive('loading',{});

局部注册

与全局注册大致相同,需配置于组件的directives配置项中

export default {
  directives: {
    // 在模板中启用 v-loading
    loading: {
      /* ... */
    }
  }
}

实例

以加载中效果为例,使用svg图片作为img.src来实现

需要多处使用,使用全局注册

// 导入配置对象/函数
import vLoading from './directives/loading';
// 注册全局自定义指令
Vue.directive('loading',vLoading);

配置项配置(以下省略样式内容):

使用es6自定义属性来锁定这个特定的img元素

// vLoading
import loadingSrc from '@/assets/loading.svg';
/**
 * 判断是否含有loading子元素
 * @param {Element} el 
 */
function getLoading(el){
    return el.querySelector('img[data-role=loading]');
}


/**
 * 创建loading
 */
function createLoading(){
    const loading = document.createElement('img');
    loading.src = loadingSrc;
    loading.dataset.role = "loading";
    return loading;
}

/**
 * 导出指令的配置对象/函数导出指令的配置对象/函数
 * @param {Element} el 
 * @param {Object} banding 
 */
export default function(el,banding){
    // 根据banding.value来确定添加/删除loading
    const isLo = getLoading(el);
    if(banding.value){
        if(!isLo){
            const img = createLoading();
            el.appendChild(img);
        }
    }else{
        if(isLo)
            el.removeChild(isLo);
    }
}

组件使用变量isLoading控制loading图片的显示:

<template>
  <div class="home-container" ref="home" @wheel="handleWheel"
    v-loading="isLoading"
  >
  </div>
</template>

<script>
import CarouselItem from './CarouselItem.vue';
import Icon from '@/components/Icon/index.vue';
import {getBanner} from '@/api/banner.js';
export default {
  data(){
    return{
      isLoading: true,    // 显示缓冲图片
    }
  },
  created(){
    getBanner().then((value)=>{
      // 数据加载后清除loading
      this.isLoading = false;
      this.data = value;
      // console.log(this.data);
      
    })
  },
 }

原文地址:https://blog.csdn.net/qq_53922901/article/details/142614799

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!