精华内容
下载资源
问答
  • v-loading的使用(ElementUI)
    千次阅读
    2021-05-21 10:52:14

    前言:需要获取后端接口数据到页面上进行显示,所以在请求发起至数据渲染页面的这段时间,为页面提供一个 loading 加载是极为必要的。
    1.区域加载
        以 table 表格为例,使用 v-loading,为其绑定一个布尔值(true/false),代码如下:

    <template>
      <div id="index">
      <!-- 表格 -->
        <el-table :data="tableData" v-loading="loading">
          <el-table-column type="selection"></el-table-column>
          <el-table-column sortable prop="name" label="姓名"></el-table-column>
          <el-table-column sortable prop="number" label="代号"></el-table-column>
          <el-table-column sortable prop="age" label="年龄"></el-table-column>
          <el-table-column sortable prop="sex" label="性别">
            <template slot-scope="scope">
              <el-tag :type="scope.row.sex === '1' ? 'primary' : 'success'" disable-transitions>
                {{scope.row.sex==='1'? '男': '女'}}</el-tag>
            </template>
          </el-table-column>
        </el-table>
       </div>
    </template>
    
    <script>
    export default {
      name: "index",
      data () {
        return {
          loading: false,   // 默认为false不显示加载
          tableData:[]   // 数据
        }
      },
      created() {
        // 调用获取数据方法
        this.getdata()
      },
      methods: {
      	// 获取数据方法
      	getdata() {
      	  this.loading = true
          // 模拟获取接口数据
          setTimeout(() => {
          	this.tableData = [  // 模拟数据
            {
              name: 'wangfu',
              number: '001',
              age: '24',
              sex: '1'
            },
            {
              name: 'wangfu',
              number: '001',
              age: '24',
              sex: '1'
            }
          	],
            this.loading = false
          }, 1000)
      	}
      }
    }
    

    2.自定义加载
        添加 element-loading-text 属性为加载文字显示在加载图标的下方, element-loading-spinner 属性为设定图标的类名,element-loading-background 属性为背景色值,代码如下:

    <el-table :data="tableData" 
    	v-loading="loading"
        element-loading-text="拼命加载中"
        element-loading-spinner="el-icon-loading"
        element-loading-background="rgba(0, 0, 0, 0.8)"></el-table>
    `
    3.整页加载
    &nbsp;&nbsp;&nbsp;&nbsp;使用指令方式来实现整页加载时,全屏遮罩需要添加fullscreen修饰符(遮罩会插入至 body 上),此时若需要锁定屏幕的滚动,可以使用lock修饰符,代码如下:
    ```javascript
    v-loading.fullscreen.lock="loading"
    
    更多相关内容
  • 剖析v-loading源码 在工作中主要做pc端的后台系统,使用的ui库为elementui,相信使用vue的小伙伴对其并不陌生,下面我就对其中的v-loding的源码进行剖析 loading.vue <template> <transition name="el-loading-fade...

    钩子函数
    一个指令定义对象可以提供如下几个钩子函数 (均为可选):

    • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
    • inserted:被绑定元素插入父节点时调用
      (仅保证父节点存在,但不一定已被插入文档中)。
    • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode
      更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。

    我们会在稍后讨论渲染函数时介绍更多 VNodes 的细节。

    • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
    • unbind:只调用一次,指令与元素解绑时调用。

    接下来我们来看一下钩子函数的参数 (即 el、binding、vnode 和 oldVnode)。

    钩子函数参数

    • el:指令所绑定的元素,可以用来直接操作 DOM。
    • binding:一个对象,包含以下 property:
    • name:指令名,不包括 v- 前缀。
    • value:指令的绑定值,例如:v-my-directive=“1 + 1” 中,绑定值为 2。
    • oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
    • expression:字符串形式的指令表达式。例如 v-my-directive=“1 + 1” 中,表达式为 “1 + 1”。
    • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 “foo”。
    • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true,
      bar: true }。
    • vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
    • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

    剖析v-loading源码
    在工作中主要做pc端的后台系统,使用的ui库为elementui,相信使用vue的小伙伴对其并不陌生,下面我就对其中的v-loding的源码进行剖析

    loading.vue

    <template>
      <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>
        </div>
      </transition>
    </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>
    

    directive.js

    import Vue from 'vue';
    import Loading from './loading.vue';
    // addClass为对应元素添加类名,removeClass删除对应的类名  getStyle获取对应的行内属性
    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';
    // 使用loading组件配置项创建vue子类构造函数
    const Mask = Vue.extend(Loading);
    
    const loadingDirective = {};
    loadingDirective.install = Vue => {
      // 是服务端渲染直接返回
      if (Vue.prototype.$isServer) return;
      const toggleLoading = (el, binding) => {
        if (binding.value) {
          Vue.nextTick(() => {
            // 一个包含修饰符的对象 eg:v-loading.fullscreen.lock="fullscreenLoading" 获取是否使用fullscreen操作符
            // 当使用指令方式时,全屏遮罩需要添加fullscreen修饰符(遮罩会插入至 body 上)
            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');
              // Loading 遮罩会插入到绑定元素的子节点,通过添加body修饰符,可以使遮罩插入至 DOM 中的 body 上
              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;
          // 表示loading组件是否隐藏
          el.instance.hiding = true;
        }
      };
      // 将对应的 loading组件渲染出来的dom插入到parent对应的dom上
      const insertDom = (parent, el, binding) => {
        // 若在前一个全屏 Loading 关闭前再次调用全屏 Loading,并不会创建一个新的 Loading 实例,而是返回现有全屏 Loading 的实例(当el.domVisible为true时说明loading组件已经插入到页面上了)
        if (!el.domVisible && getStyle(el, 'display') !== 'none' && getStyle(el, 'visibility') !== 'hidden') {
          // 将行内样式赋值到loading组件渲染出的dom上
          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;
            }
          });
          // 表示已经将对应的dom插入到页面中了
          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) {
          // 获取绑定指令元素对应元素的属性值,传入到loading组件的data中
          // 在绑定了v-loading指令的元素上添加element-loading-text属性,其值会被渲染为加载文案,并显示在加载图标的下方。类似地,element-loading-spinner和element-loading-background属性分别用来设定图标类名和背景色值
          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
            }
          });
          // 将实例放到对应元素dom的instance上
          el.instance = mask;
          // 将实例loading组件渲染出来的dom放到mask属性上
          el.mask = mask.$el;
          // 存放loading渲染出来的dom属性的行内样式
          el.maskStyle = {};
          // 当值为true时调用
          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) {
          // domInserted是否插入到页面的标识,在insertDom方法中被赋值为true
          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;
    
    展开全文
  • v-loading

    千次阅读 2019-10-29 17:32:37
    element-ui 内置的 v-loading 指令非常友好,只需要提供一个 Boolean 值就能实现加载动画的一个指令。 具体的使用方法归纳为:接口请求到数据之前,显示加载中。接口请求到数据之后,消失。 项目案例截图: 具体的...

    element-ui 内置的 v-loading 指令非常友好,只需要提供一个 Boolean 值就能实现加载动画的一个指令。
    具体的使用方法归纳为:接口请求到数据之前,显示加载中。接口请求到数据之后,消失。

    项目案例截图:
    具体的功能为当我点击“查询”按钮之后,对应的查询清单list会呈现出来
    在这里插入图片描述
    首先在需要加载的dom中加入v-loading=“loading”
    在这里插入图片描述
    在data 中定义初始化, loading: false,同时在mounted()中将 this.loading设置为true,再去请求接口。
    同时在接口的回调函数中,将 this.loading 设为false,到达效果。
    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 自定义指令 v-loading

    2021-12-17 14:06:05
    v-loading,自定义指令

    1. 在src下创建directive文件夹

    2. 在directive文件夹下创建loading文件夹

    3. loading文件夹内创建index.js和loading.vue

    目录图:

     4. index.js

    // src/directive/loading/index.js
    
    import Vue from 'vue'
    import Loading from './loading.vue'
    
    /**
     * Vue.extend 接受参数并返回一个构造器,new 该构造器可以返回一个组件实例
     * 当我们 new Mask() 的时候,把该组件实例挂载到一个 div 上
     **/
     const Mask = Vue.extend(Loading)
    
    /**
     * 如果loading.vue组件是模式export default vue.extend({})
     * 则直接用下面的这一行代码就行
     **/
     // const Mask = Loading
    
    // 更新是否显示
    const toggleLoading = (el, binding) => {
      if (binding.value) {
        Vue.nextTick(() => {
          // 控制loading组件显示
          el.instance.visible = true
          // 插入到目标元素
          insertDom(el, el, binding)
        })
      } else {
        el.instance.visible = false
      }
    }
    
     //插入到目标元素
    const insertDom = (parent, el) => {
      parent.appendChild(el.mask)
    }
    
    export default {
      //第一次绑定到元素时调用
      bind: function (el, binding, vnode) {
        console.log("el",el,"binding",binding)
        const mask = new Mask({
          el: document.createElement('div'),
          data () {}
        })
        //用一个变量接住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, binding) {
        el.instance && el.instance.$destroy()
      }
    }
    

    5. loading.vue

    // src/directive/loading/Loading.vue
    <template>
      <div v-show="visible" class="loading-wrap">
        <div class="loading-box">加载中...</div>
      </div>
    </template>
    
    <script>
    // import Vue from "vue";
    // export default Vue.extend({
    //   data() {
    //     return {
    //       visible: true,
    //     };
    //   },
    // });
    export default {
      data() {
        return {
          visible: true,
        };
      },
    };
    </script>
    <style lang="scss" scoped>
    .loading-wrap {
      position: relative;
      width: 100%;
      height: 100%;
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
      background: rgba(0, 0, 0, 0.5);
    }
    .loading-box {
      position: relative;
      left: 50%;
      top: 50%;
      width: 100px;
      transform: translate(-50%, -50%);
    }
    </style>
    

    6. directive下的index.js

    import Loading from "./loading"
    export default {
      install(Vue) {
        Vue.directive("loading", Loading);
      },
    };
    

    7. main.js中使用插件

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

    8. 项目中使用

    <template>
      <div class="app-container">
        <div class="loading">
            <el-button class="btn" size="mini" @click="loadingClick">loading</el-button>
          <div class="loading-div" v-loading="loading"></div>
        </div>
      </div>
    </template>
    
    <script>
    
    export default {
      data() {
        return {
          loading: false,
        };
      },
      methods: {
        loadingClick (){
          this.loading = true;
          setTimeout(() => {
            this.loading =  false
          },2000)
        }
      },
    };
    
    </script>
    
    <style lang="scss" scoped>
    
    .loading {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 100%;
      height: 50px;
      border: solid gray 1px;
      .btn {
        margin-right: 10px;
      }
      .loading-div {
        display: inline-block;
        border: solid red 1px;
        width: 200px;
        height: 40px;
      }
    }
    
    </style>

    8. 效果

     

    展开全文
  • 手写 vue 自定义指令 v-loading 目标效果: 在vue项目的标签里面使用 v-loading="true" ,如同element-ui里面使用v-loading一样 会展示loading 效果。 在这里我做两个laoding效果: 一个全屏的loading效果,用于...
  • element-plus dialog v-loading不生效

    千次阅读 2022-01-23 19:31:57
    el-dialog的v-loading 这样使用没反应。 解决 定义ref 并使用 ElLoading.service setup定义 const me = ref(null) ElLoading.service({ target: me.value.dialogRef }) 结束语 为什么v-loading不生效,有人知道...
  • 自定义加载效果的loading指令 为什么不创建一个组件来加载loading效果: 麻烦你得先引入组件,注册挂载组件,然后在通过v-if在空子显示隐藏 为什么要用自定义loading指令: 由于项目中很多地方需要用到,在...
  • 记录 element-ui v-loading 指令 instance.close() 报错问题 背景 解决 sentry issues 时看到一个这样的报错 TypeError: Cannot read properties of undefined (reading ‘close’) 报错的代码来自 element-plus ...
  • (vue3.x自定义v-loading思路类似) directive.js import Loading from './loading'; import Vue from 'vue'; const loadingDirective = { inserted(el, binding){ const loading = Vue.extend(Loading); el....
  • 新建一个loading文件夹(新建index.js、loading.js、loading.vue) index.js import loading from './loading' export default { install (Vue) { Vue.directive('loading', loading) } } loading.js // ...
  • vue自定义指令v-loading

    万次阅读 2021-07-14 13:28:49
    1.在 src目录下创建一个directiveLoading文件夹,然后这个文件夹下创建1个loading文件夹和index.js文件,loading文件夹下分别创建Loading.vue和index.js文件。 directiveLoading的index.js文件用来暴露安装插件接口...
  • element-ui的v-loading不生效

    千次阅读 2021-08-25 14:06:07
    按照官方文档引入Loading后,全局引入位置加 Vue.use(Loading.directive);
  • 使用v-loading报错 无法找到样式 element-plus/es/components/loading-directive/style/css 解决办法: element-plus版本: "element-plus": "^2.1.9" "unplugin-auto-import": "^0.7.1", "unplugin-vue-...
  • element-loading-text="数据加载中..." class="loading-map" icon颜色和字体颜色 <style> /* 地图上的loading样式 */ .loading-map .el-loading-mask { z-index: 0 !important; background-color: rgba(0...
  • 1、准备loading.js import Vue from 'vue' /** * 插入loading */ const insertDom = (el) =>...div class="el-loading-mask"> <div class="el-loading-spinner"> <svg viewBox="25 25 50 50" cl
  • <div> <div v-show="loadingVisible" ... element-loading-background="rgba(2, 25, 51, 0.3)" element-loading-text="匹配中" > </div> <div> //主体内容 </div> <
  • vue v-loading指令

    千次阅读 2019-11-14 20:06:48
    <template> .course-wrapper(v-loading='Object.keys(resource).length <= 0') </template> v-loading的作用:在请求到数据...(如果)v-loading写在template的顶层元素上,不会触发全局loading。...
  • ./components/loading/loading.vue ...div class="loading-content"> <img width="24" height="24" src="./loading.gif" /> <p class="desc">{{ title }}</p> </div> <
  • 记录一下v-loading="tableloading"使用 在table数据渲染时使用,HTML中添加: v-loading=“tableloading” <el-table ref="dynamictable" :data="form.coldata" v-loading="tableloading" tooltip-effect=...
  • 根据需求,由预览按钮打开弹窗,且弹窗需要渲染的数据较多,渲染的速度比较慢,所以要加一个加载中的效果,element ui的 v-loading属性就正好可以解决这一需求,但是当加入这一属性之后发现,是实现了加载功能,但是...
  • v-loading修改z-index

    千次阅读 2021-01-09 01:02:16
    <template> <div :id="id" :class="className" :style="{height:height,width:width}" v-loading="loading" ... element-loading-spinner="el-icon-loading"/> </template> <script&g.
  • element之v-loading以及颜色修改

    千次阅读 2021-01-13 11:04:00
    当你已经发送了请求,但是数据还没有请求回来的时候,呈现一个数据正在加载的状态,可以通过v-loading指令来展示加载状态。 只需要把v-loading的值绑定为true或false即可。 <el-table v-loading="loading" :data=...
  • v-loading在可变高度元素上使用时,元素出现竖向滚动条时,loading无法全覆盖此时可用v-loading.body指令即可
  • vue3自定义v-loading指令directives 1.在项目的src下创建一个directives...div class="loading-container"> <Loading size="300" /> </div> </template> <script lang="ts"> import {
  • elementUI v-loading不显示问题

    千次阅读 2021-03-04 17:55:30
    elementUI v-loading不显示问题问题描述:解决办法:**分析:** 问题描述: 1. data(){listLoading:true}中已经声明了 2.el-table中绑定了这个属性 3.methods:{}中请求接口中也写了赋值操作(为什么不显示?)...
  • <div class="tool-container" v-loading="loading" element-loading-text="数据加载中,请稍后……" ... element-loading-custom-class="loading-icon" > </div> 绑定的类loading-ico
  • .el-loading-spinner .circular{ width: 42px; height: 42px; animation: loading-rotate 2s linear infinite; display: none; } .el-loading-spinner{ background: url(./assets/img/loading-1.gif) no-repeat...
  • el-card v-loading="loading" shadow="hover" element-loading-background="rgba(0, 0, 0, 0)" > 在data里定义loading变量,初始值为true。在请求后台的前面写loading=true,后面写loading=false。 加载的时候会...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 94,038
精华内容 37,615
关键字:

v-loading