vue3.0 注册全局自定义指令

6,105 阅读2分钟

前言

在使用vue开发项目的过程中,若是我们需要对普通 DOM 元素进行底层操作时,一般都会考虑通过自定义指令来解决。但,考虑到有些同学可能还没用过这个神奇又简便的功能,所以这里就向同学们举一个简单的例子:回到顶部,以便帮助大家快速掌握。

注意:若是还没学习过自定义指令,一定要先去官网阅读学习。

案例

功能介绍

点击可以回到顶部,按钮可以显示或隐藏。

参数

参数说明类型
id给父级元素(注:固定高且内容可滚动)添加id,实现局部回到顶部String可选
num偏移距离值,用于显示或隐藏Number必选

使用方式

方式一 整体滚动

<div v-backtop="100"> 顶部1 </div>

方式二 局部滚动

<div v-backtop:wu="50"> 顶部2 </div>

源码

vbacktop.js

定义指令功能。为方便管理,一个模块即文件,只定义一个指令。

export default {
  mounted(el, binding) {
    const ele = document.getElementById(binding.arg);
    const target = ele || window;
    const type = ele ? 1 : 2;

    // 点击监听
    el.addEventListener('click', () => {
      if (ele) {
        smooth(target);
      } else {
        target.scrollTo({
          top: 0,
          behavior: 'smooth'
        });
      }
    });
    // 滚动监听
    target.addEventListener('scroll', (e) => {
      const doc = type === 1 ? (e.target || e.srcElement) : 
            (e.target.documentElement || e.srcElement.documentElement);
      
      if (doc.scrollTop > binding.value) {
        el.style.visibility = 'unset';
      } else {
        el.style.visibility = 'hidden';
      }
    });

    el.style.visibility = 'hidden'; // 默认隐藏
  },
  unmounted(el, binding) {
    const target = binding.arg ? document.getElementById(binding.arg) : window;
    target.removeEventListener('scroll');
    el.removeEventListener('click');
  }
}

// 平滑移动,里面的数值都可以使用参数形式传入。这里直接写成固定值了。
function smooth(ele) {
  let distance = ele.scrollTop;
  const step = (distance / 300) * 10;
  const timer = setInterval(() => {
    distance = distance - step;
    if (distance <= 0) {
      clearInterval(timer);
      ele.scrollTop = 0;
      return false;
    }
    ele.scrollTop = distance;
  }, 10);
}

index.js

注册指令

import backtop from './vbacktop' // 引入指令

const directives = { // 指令对象
    backtop
}

export default {
    install(app) {
      Object.keys(directives).forEach((key) => {
        app.directive(key, directives[key])
      });
    }
}

main.js

引入并调用。注意,vue3.0 相较于 2.0 有所改动。不清楚的,可以去看看官方文档。

import { createApp } from 'vue';
import App from './App.vue';
import directives from './directives/index';

const app = createApp(App);
app.use(directives) // 调用安装指令

app.mount('#app');

使用指令

WeChatab446a7abec5767d06bc003ef93a87f4.png

展示

滚动整个文档

WeChatddd1868061f22ac0ab2af9595aae1030.png

滚动父级元素中的内容(父级要有固定高)

WeChat4404dae6de5d3a24245220858481d333.png