使用Vue.extend将UI组件转为js组件,通过函数调用来创建组件

一、示例效果

封装一个loading效果,通过函数去调用

加载时创建DOM,加载完删除DOM

二、Loading的封装

1. components/Loading/index.vue

js 复制代码
<template>
  <div class="loader">
    <div class="loader-inner">
      <div class="loader-line-wrap">
        <div class="loader-line"></div>
      </div>
      <div class="loader-line-wrap">
        <div class="loader-line"></div>
      </div>
      <div class="loader-line-wrap">
        <div class="loader-line"></div>
      </div>
      <div class="loader-line-wrap">
        <div class="loader-line"></div>
      </div>
      <div class="loader-line-wrap">
        <div class="loader-line"></div>
      </div>
    </div>
  </div>
</template>

<style lang="less" scoped>
.loader {
  background: rgba(0, 0, 0, 0.2);
  bottom: 0;
  left: 0;
  overflow: hidden;
  position: fixed;
  right: 0;
  top: 0;
  z-index: 99999;
}
.loader-inner {
  bottom: 0;
  height: 60px;
  left: 0;
  margin: auto;
  position: absolute;
  right: 0;
  top: 0;
  width: 100px;
}
.loader-line-wrap {
  animation: spin 2000ms cubic-bezier(0.175, 0.885, 0.32, 1.275) infinite;
  box-sizing: border-box;
  height: 50px;
  left: 0;
  overflow: hidden;
  position: absolute;
  top: 0;
  transform-origin: 50% 100%;
  width: 100px;
}
.loader-line {
  border: 4px solid transparent;
  border-radius: 100%;
  box-sizing: border-box;
  height: 100px;
  left: 0;
  margin: 0 auto;
  position: absolute;
  right: 0;
  top: 0;
  width: 100px;
}
.loader-line-wrap:nth-child(1) {
  animation-delay: -50ms;
}
.loader-line-wrap:nth-child(2) {
  animation-delay: -100ms;
}
.loader-line-wrap:nth-child(3) {
  animation-delay: -150ms;
}
.loader-line-wrap:nth-child(4) {
  animation-delay: -200ms;
}
.loader-line-wrap:nth-child(5) {
  animation-delay: -250ms;
}
.loader-line-wrap:nth-child(1) .loader-line {
  border-color: hsl(0, 80%, 60%);
  height: 90px;
  width: 90px;
  top: 7px;
}
.loader-line-wrap:nth-child(2) .loader-line {
  border-color: hsl(60, 80%, 60%);
  height: 76px;
  width: 76px;
  top: 14px;
}
.loader-line-wrap:nth-child(3) .loader-line {
  border-color: hsl(120, 80%, 60%);
  height: 62px;
  width: 62px;
  top: 21px;
}
.loader-line-wrap:nth-child(4) .loader-line {
  border-color: hsl(180, 80%, 60%);
  height: 48px;
  width: 48px;
  top: 28px;
}
.loader-line-wrap:nth-child(5) .loader-line {
  border-color: hsl(240, 80%, 60%);
  height: 34px;
  width: 34px;
  top: 35px;
}
@keyframes spin {
  0%,
  15% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}
</style>

2. components/Loading/index.js

js 复制代码
import Vue from "vue";
import LoadingUI from "./index.vue";

const instance = () => {
  const JSloading = Vue.extend(LoadingUI);
  const loadingVm = new JSloading().$mount();
  return {
    show() {
      document.body.appendChild(loadingVm.$el);
    },
    hide() {
      loadingVm.$el.remove();
    }
  }
}
export default instance()

三、使用

1. 单文件引入使用

js 复制代码
import loading from "@/components/Loading";


    async getList() {
      try {
        loading.show();
        const res = await listApi1();
        console.log(res);
      } catch (err) {
        console.log(err);
      } finally {
        loading.hide();
      }
    }

2. 或者在main.js中进行全局注册

main.js

js 复制代码
import loading from "@/components/Loading";
Vue.prototype.$loading = loading

使用时不需要引入,直接通过this调用

js 复制代码
    async getList() {
      try {
        this.$loading.show();
        const res = await listApi1();
        console.log(res);
      } catch (err) {
        console.log(err);
      } finally {
        this.$loading.hide();
      }
    }

3. 也可以在axios拦截器中,给所有的接口都添加上loading

js 复制代码
import axios from 'axios'
import loading from "@/components/Loading";

const service = axios.create()

// request 拦截器
service.interceptors.request.use(
  config => {
    loading.show()
    return config
  },
  error => {
    loading.hide()
    return Promise.reject(error)
  }
)

// response 拦截器
service.interceptors.response.use(
  response => {
    loading.hide()
    return response.data.data
  },
  error => {
    loading.hide()
    return Promise.reject(error)
  }
)

export default service

类似的例子:www.cnblogs.com/wuqilang/p/...

相关推荐
小粉粉hhh22 分钟前
React(二)——dom、组件间通信、useEffect
前端·javascript·react.js
Csvn30 分钟前
🤖 AI 生成前端代码的 5 个典型翻车现场及修复指南
前端
IT_陈寒1 小时前
SpringBoot自动装配坑了我一天,原来问题出在这
前端·人工智能·后端
索西引擎2 小时前
【React】key 属性:协调算法中的元素标识机制与最佳实践
前端·javascript·react.js
只会cv的前端攻城狮3 小时前
动态组件架构设计:从配置到事件驱动全链路解析
前端·vue.js
飞天狗3 小时前
Next.js 16 App Router 实战:服务端组件与流式渲染
前端·next.js
OpenTiny社区3 小时前
TinyEngine 2.11版本发布:AI 进一步融入画布,Vue 工程可一键转DSL
前端·vue.js·github
小雪_Snow3 小时前
JavaScript 中的三种常用事件
开发语言·前端·javascript
Hyyy3 小时前
Electron-Vite是什么,和Vite有什么区别
前端·面试
蓝胖子酱3 小时前
在 Electron 中用 electron-store 实现加密存储与自定义格式文件
前端·javascript·数据库