当前位置 : 主页 > 网络编程 > JavaScript >

lottie实现vue自定义loading指令及常用指令封装详解

来源:互联网 收集:自由互联 发布时间:2023-02-08
目录 一、前言 二、实现方式 1.v-loading 2.v-click-outside 三、后记 一、前言 本文主要介绍使用lottie动画实现vue自定义loading的指令方法。另外本篇文章还会介绍其他几个常用的自定义指令实
目录
  • 一、前言
  • 二、实现方式
    • 1.v-loading
    • 2.v-click-outside
  • 三、后记

    一、前言

    本文主要介绍使用lottie动画实现vue自定义loading的指令方法。另外本篇文章还会介绍其他几个常用的自定义指令实现方式(点击指定区域外监听指令)。

    lottie是一款由airbnb开源的跨平台动画渲染库,支持Android,iOS,Web,Windows平台。是专门用于解析从AE(Adobe After Effects)中通过Bodymovin插件导出的JSON文件,直接渲染动画。

    二、实现方式

    1.v-loading

    这个指令是我们在开发过程中经常遇到的场景,这里我们分两步做,第一步我们先创建一个loading的组件。

    这里我们要先引入lottie插件

    npm install lottie-web
    // or
    yarn add lottie-web
    

    之后在loading组件中引入

    // loading.vue
    <template>
      <div class="loading-wrap">
        <div id="loadingImg" />
      </div>
    </template>
    <script>
    import lottie from "lottie-web"
    // 在网上下载的lottie动画,这里我是在iconfont上找的
    import animationData from "./loading.json"
    export default {
      mounted() {
        // 解决json动画找不到dom不渲染问题
        window.requestAnimationFrame(this.loadImg);
      },
      methods: {
        loadImg () {
          lottie.loadAnimation({
            container: document.getElementById('loadingImg'),
            renderer: "svg",
            loop: true,
            autoplay: true,
            animationData: animationData
          });
        }
      }
    };
    </script>
    <style lang="less" scoped>
    .loading-wrap {
      position: absolute;
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
      background-color: #fff;
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 1800;
    }
    </style>
    

    然后去在创建一个js文件去写指令

    import Vue from 'vue'
    import Loading from './loading.vue'
    /**
     * Vue.extend 接受参数并返回一个构造器,new 该构造器可以返回一个组件实例
     * 当我们 new Mask() 的时候,把该组件实例挂载到一个 div 上
     **/
    const Mask = Vue.extend(Loading)
    // 更新是否显示
    const toggleLoading = (el, binding) => {
      if (binding.value) {
        Vue.nextTick(() => {
          // 获取父元素的定位信息
          const isStatic = window.getComputedStyle(el).position === 'static'
          if (isStatic) {
            el.style.position = 'relative'
          }
          // 插入到目标元素
          insertDom(el, el, binding)
        })
      } else {
        removeDom(el, el, binding)
      }
    }
    // 插入到目标元素
    const insertDom = (parent, el) => {
      parent.appendChild(el.mask)
    }
    // 从目标元素中移除
    const removeDom = (parent, el) => {
      parent.removeChild(el.mask)
    }
    export default {
      // 第一次绑定到元素时调用
      bind: function (el, binding) {
        const mask = new Mask({
          el: document.createElement('div')
        })
        // 用一个变量接住mask实例
        el.instance = mask
        el.mask = mask.$el
        el.maskStyle = {}
        binding.value && toggleLoading(el, binding)
      },
      // 所在组件的 VNode 更新时调用--比较更新前后的值
      update: function (el, binding) {
        if (binding.oldValue !== binding.value) {
          toggleLoading(el, binding)
        }
      },
      // 指令与元素解绑时调用
      unbind: function (el) {
        el.instance && el.instance.$destroy()
      }
    }
    

    然后我们再去main.js中,全局注册一下

    import Directive from './directives'
    Vue.use(Directive)
    

    最后,在使用的时候,就可以这样

     // App.vue
     <template>
      <div id="app" v-loading="isLoading">
      </div>
    </template>
    <script>
    export default {
      name: 'App',
      data () {
        return {
          isLoading: true
        }
      },
      mounted () {
        setTimeout(() => {
          this.isLoading = false
        }, 3000)
      }
    }
    </script>
    

    以上 我们就封装好了一个lottie的自定义loading。

    2.v-click-outside

    这个指令是点击目标区域以外的地方的监听。在日常开发中,我们可能会遇到自定义的一些弹窗效果,这个时候,这个指令就派上用场了。

    // clickoutside.js
    export default {
      bind (el, binding, vnode) {
        function documentHandler (e) {
          if (el.contains(e.target)) {
            return false
          }
          if (binding.expression) {
            binding.value(e)
          }
        }
        el.__vueClickOutside__ = documentHandler
        document.addEventListener('click', documentHandler)
      },
      update () {
      },
      unbind (el, binding) {
        document.removeEventListener('click', el.__vueClickOutside__)
        delete el.__vueClickOutside__
      }
    }
    

    之后是使用方法, 如下

    <template>
      <div id="app">
        <img  v-click-outside="handleOutSide" src="./assets/logo.png" >
      </div>
    </template>
    <script>
    export default {
      name: 'App',
      methods: {
        handleOutSide () {
          console.log('到外面了')
        }
      }
    }
    </script>
    

    最后记得在index.js中将两个指令定义一下,再去main.js中注册到全局。

    import Loading from './loading'
    import clickoutside from './clickoutside'
    export default {
      install (Vue) {
        Vue.directive('loading', Loading),
        Vue.directive('click-outside', clickoutside)
      }
    }
    

    目录结构如图

    以上我们就实现了常用指令的自定义。

    三、后记

    关于自定义指令有非常多,比如权限时候可能会用到、占位图、loading等。我们都可以用指令的封装,快速便捷的实现一些功能。

    以上就是lottie实现vue自定义loading指令及常用指令封装的详细内容,更多关于lottie vue自定义loading指令的资料请关注易盾网络其它相关文章!

    网友评论