最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue如何使用element組件自定義v-loading

 更新時間:2024年08月27日 09:35:03   作者:Billow_lamb  
這篇文章主要介紹了vue如何使用element組件自定義v-loading問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

使用element組定義v-loading

文件夾目錄

src文件夾下面的directive.js

import Vue from 'vue';
import Loading from './loading.vue';
import { addClass, removeClass, getStyle } from 'element-ui/src/utils/dom';
import { PopupManager } from 'element-ui/src/utils/popup';
import afterLeave from 'element-ui/src/utils/after-leave';
const Mask = Vue.extend(Loading);
// Mask 是一個虛擬DOM
const loadingDirective = {};
loadingDirective.install = Vue => {
  if (Vue.prototype.$isServer) return;
  const toggleLoading = (el, binding) => {
    if (binding.value) {
      Vue.nextTick(() => {
        if (binding.modifiers.fullscreen) {
          el.originalPosition = getStyle(document.body, 'position');
          el.originalOverflow = getStyle(document.body, 'overflow');
          el.maskStyle.zIndex = PopupManager.nextZIndex();

          addClass(el.mask, 'is-fullscreen');
          insertDom(document.body, el, binding);
        } else {
          removeClass(el.mask, 'is-fullscreen');

          if (binding.modifiers.body) {
            el.originalPosition = getStyle(document.body, 'position');

            ['top', 'left'].forEach(property => {
              const scroll = property === 'top' ? 'scrollTop' : 'scrollLeft';
              el.maskStyle[property] = el.getBoundingClientRect()[property] +
                document.body[scroll] +
                document.documentElement[scroll] -
                parseInt(getStyle(document.body, `margin-${ property }`), 10) +
                'px';
            });
            ['height', 'width'].forEach(property => {
              el.maskStyle[property] = el.getBoundingClientRect()[property] + 'px';
            });

            insertDom(document.body, el, binding);
          } else {
            el.originalPosition = getStyle(el, 'position');
            insertDom(el, el, binding);
          }
        }
      });
    } else {
      afterLeave(el.instance, () => {
        if (!el.instance.hiding) return;
        el.domVisible = false;
        const target = binding.modifiers.fullscreen || binding.modifiers.body
          ? document.body
          : el;
        removeClass(target, 'el-loading-parent--relative');
        removeClass(target, 'el-loading-parent--hidden');
        el.instance.hiding = false;
      }, 300, true);
      el.instance.visible = false;
      el.instance.hiding = true;
    }
  };
  const insertDom = (parent, el, binding) => {
    if (!el.domVisible && getStyle(el, 'display') !== 'none' && getStyle(el, 'visibility') !== 'hidden') {
      Object.keys(el.maskStyle).forEach(property => {
        el.mask.style[property] = el.maskStyle[property];
      });

      if (el.originalPosition !== 'absolute' && el.originalPosition !== 'fixed') {
        addClass(parent, 'el-loading-parent--relative');
      }
      if (binding.modifiers.fullscreen && binding.modifiers.lock) {
        addClass(parent, 'el-loading-parent--hidden');
      }
      el.domVisible = true;

      parent.appendChild(el.mask);
      Vue.nextTick(() => {
        if (el.instance.hiding) {
          el.instance.$emit('after-leave');
        } else {
          el.instance.visible = true;
        }
      });
      el.domInserted = true;
    } else if (el.domVisible && el.instance.hiding === true) {
      el.instance.visible = true;
      el.instance.hiding = false;
    }
  };
  Vue.directive('loading', { // 自定義全局指令
    bind: function(el, binding, vnode) {
      const textExr = el.getAttribute('element-loading-text');
      const spinnerExr = el.getAttribute('element-loading-spinner');
      const backgroundExr = el.getAttribute('element-loading-background');
      const customClassExr = el.getAttribute('element-loading-custom-class');
      const vm = vnode.context;
      const mask = new Mask({
        el: document.createElement('div'),
        data: {
          text: vm && vm[textExr] || textExr,
          spinner: vm && vm[spinnerExr] || spinnerExr,
          background: vm && vm[backgroundExr] || backgroundExr,
          customClass: vm && vm[customClassExr] || customClassExr,
          fullscreen: !!binding.modifiers.fullscreen
        }
      });
      el.instance = mask;
      el.mask = mask.$el;
      el.maskStyle = {};

      binding.value && toggleLoading(el, binding);
    },
    update: function(el, binding) {
      el.instance.setText(el.getAttribute('element-loading-text'));
      if (binding.oldValue !== binding.value) {
        toggleLoading(el, binding);
      }
    },
    unbind: function(el, binding) {
      if (el.domInserted) {
        el.mask &&
        el.mask.parentNode &&
        el.mask.parentNode.removeChild(el.mask);
        toggleLoading(el, { value: false, modifiers: binding.modifiers });
      }
      el.instance && el.instance.$destroy();
    }
  });
};

export default loadingDirective;

index.js

import Vue from 'vue';
import loadingVue from './loading.vue';
import { addClass, removeClass, getStyle } from 'element-ui/src/utils/dom';
import { PopupManager } from 'element-ui/src/utils/popup';
import afterLeave from 'element-ui/src/utils/after-leave';
import merge from 'element-ui/src/utils/merge';

const LoadingConstructor = Vue.extend(loadingVue);

const defaults = {
  text: null,
  fullscreen: true,
  body: false,
  lock: false,
  customClass: ''
};

let fullscreenLoading;

LoadingConstructor.prototype.originalPosition = '';
LoadingConstructor.prototype.originalOverflow = '';

LoadingConstructor.prototype.close = function() {
  if (this.fullscreen) {
    fullscreenLoading = undefined;
  }
  afterLeave(this, () => {
    const target = this.fullscreen || this.body
      ? document.body
      : this.target;
    removeClass(target, 'el-loading-parent--relative');
    removeClass(target, 'el-loading-parent--hidden');
    if (this.$el && this.$el.parentNode) {
      this.$el.parentNode.removeChild(this.$el);
    }
    this.$destroy();
  }, 300);
  this.visible = false;
};

const addStyle = (options, parent, instance) => {
  let maskStyle = {};
  if (options.fullscreen) {
    instance.originalPosition = getStyle(document.body, 'position');
    instance.originalOverflow = getStyle(document.body, 'overflow');
    maskStyle.zIndex = PopupManager.nextZIndex();
  } else if (options.body) {
    instance.originalPosition = getStyle(document.body, 'position');
    ['top', 'left'].forEach(property => {
      let scroll = property === 'top' ? 'scrollTop' : 'scrollLeft';
      maskStyle[property] = options.target.getBoundingClientRect()[property] +
        document.body[scroll] +
        document.documentElement[scroll] +
        'px';
    });
    ['height', 'width'].forEach(property => {
      maskStyle[property] = options.target.getBoundingClientRect()[property] + 'px';
    });
  } else {
    instance.originalPosition = getStyle(parent, 'position');
  }
  Object.keys(maskStyle).forEach(property => {
    instance.$el.style[property] = maskStyle[property];
  });
};
const Loading = (options = {}) => {
  if (Vue.prototype.$isServer) return;
  options = merge({}, defaults, options);
  if (typeof options.target === 'string') {
    options.target = document.querySelector(options.target);
  }
  options.target = options.target || document.body;
  if (options.target !== document.body) {
    options.fullscreen = false;
  } else {
    options.body = true;
  }
  if (options.fullscreen && fullscreenLoading) {
    return fullscreenLoading;
  }

  let parent = options.body ? document.body : options.target;
  let instance = new LoadingConstructor({
    el: document.createElement('div'),
    data: options
  });
  addStyle(options, parent, instance);
  if (instance.originalPosition !== 'absolute' && instance.originalPosition !== 'fixed') {
    addClass(parent, 'el-loading-parent--relative');
  }
  if (options.fullscreen && options.lock) {
    addClass(parent, 'el-loading-parent--hidden');
  }
  parent.appendChild(instance.$el);
  Vue.nextTick(() => {
    instance.visible = true;
  });
  if (options.fullscreen) {
    fullscreenLoading = instance;
  }
  return instance;
};
export default Loading;

loading.vue (這是核心文件也就是在頁面怎么展示效果的v-loading)

<template>
  <div class="loading-index">
    <transition name="el-loading-fade" @after-leave="handleAfterLeave">
      <div
        v-show="visible"
        class="el-loading-mask"
        :style="{ backgroundColor: background || '' }"
        :class="[customClass, { 'is-fullscreen': fullscreen }]"
      >
        <div class="el-loading-spinner">
          <!-- <svg v-if="!spinner" class="circular" viewBox="25 25 50 50">
          <circle class="path" cx="50" cy="50" r="20" fill="none"/>
        </svg>
        <i v-else :class="spinner"></i>
        <p v-if="text" class="el-loading-text">{{ text }}</p> -->
          <div class="number">
            <span
              v-for="(item, index) in 'loading...'"
              :style="
                'animation: totop 1.5s ' + 0.1 * index + 's infinite ease-out'
              "
              :key="index"
            >
              {{ item }}
            </span>
          </div>
        </div>
      </div>
    </transition>
  </div>
</template>
<script>
export default {
  data() {
    return {
      text: null,
      spinner: null,
      background: null,
      fullscreen: true,
      visible: false,
      customClass: "",
    };
  },

  methods: {
    handleAfterLeave() {
      this.$emit("after-leave");
    },
    setText(text) {
      this.text = text;
    },
  },
};
</script>
<style lang="less">
.loading-index {
  .number {
    line-height: 250px;
    font-size: 24px;
    color: #000;
    text-align: center;
    span {
      position: relative;
      margin-right: -6px;
    }
  }
  @keyframes totop {
    0% {
      top: 0;
    }
    24% {
      top: 0;
    }
    33% {
      top: -7px;
    }
    39% {
      top: -7px;
    }
    45% {
      top: 0;
    }
    100% {
      top: 0;
    }
  }
}
</style>

在跟loading文件夾建立index.js(一定要跟src同級)

import directive from './src/directive';
import service from './src/index';
export default {
  install(Vue) {
    Vue.use(directive);
    Vue.prototype.$loading = service;
  },
  directive,
  service
};

在main.js中引入

注意:一定要注意先后順序,否責無法實現(xiàn)

效果圖片

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue渲染失敗的幾種原因及解決方案

    Vue渲染失敗的幾種原因及解決方案

    這篇文章主要介紹了Vue渲染失敗的幾種原因及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • 解決vue中axios設置超時(超過5分鐘)沒反應的問題

    解決vue中axios設置超時(超過5分鐘)沒反應的問題

    這篇文章主要介紹了解決vue中axios設置超時(超過5分鐘)沒反應的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • vue項目如何解決數(shù)字計算精度問題

    vue項目如何解決數(shù)字計算精度問題

    這篇文章主要介紹了vue項目如何解決數(shù)字計算精度問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • Vue中點擊url下載文件的案例詳解

    Vue中點擊url下載文件的案例詳解

    這篇文章主要介紹了Vue中點擊url下載文件案例詳解,此文需要注意若是文件的url存在跨域的情況,則可能會下載失敗,因為fetch請求連接后,由于跨域,拿不到資源,也就無法執(zhí)行后續(xù)的操作,此時是失敗的,詳細內(nèi)容跟隨小編一起看看吧
    2022-04-04
  • vue3-HTTP請求方式

    vue3-HTTP請求方式

    這篇文章主要介紹了vue3-HTTP請求方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • vue 動態(tài)設置瀏覽器標題的方法詳解

    vue 動態(tài)設置瀏覽器標題的方法詳解

    這篇文章主要為大家介紹了vue動態(tài)設置瀏覽器標題的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • Vue通過vue-router實現(xiàn)頁面跳轉(zhuǎn)的全過程

    Vue通過vue-router實現(xiàn)頁面跳轉(zhuǎn)的全過程

    這篇文章主要介紹了Vue通過vue-router實現(xiàn)頁面跳轉(zhuǎn)的操作步驟,文中有詳細的代碼示例和圖文供大家參考,對大家的學習或工作有一定的幫助,感興趣的朋友可以參考下
    2024-04-04
  • Vue3?props的使用示例詳解

    Vue3?props的使用示例詳解

    這篇文章主要介紹了Vue3?props的使用詳解,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-10-10
  • Vue + ts實現(xiàn)輪播插件的示例

    Vue + ts實現(xiàn)輪播插件的示例

    這篇文章主要介紹了Vue + ts實現(xiàn)輪播插件的示例,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下
    2020-11-11
  • vue使用mint-ui實現(xiàn)下拉刷新和無限滾動的示例代碼

    vue使用mint-ui實現(xiàn)下拉刷新和無限滾動的示例代碼

    本篇文章主要介紹了vue使用mint-ui實現(xiàn)下拉刷新和無限滾動的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11

最新評論

越西县| 老河口市| 青田县| 长治县| 长海县| 彭州市| 湄潭县| 龙陵县| 历史| 张家口市| 湛江市| 仪陇县| 南郑县| 齐河县| 宁都县| 柞水县| 昌邑市| 黔江区| 临澧县| 宜州市| 东阳市| 临泉县| 漳浦县| 镶黄旗| 高淳县| 桦川县| 启东市| 榕江县| 麻江县| 牙克石市| 益阳市| 泉州市| 曲阜市| 呼玛县| 丹巴县| 桑日县| 台安县| 平原县| 苏州市| 红桥区| 墨竹工卡县|