IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 普歌-实测在Nuxt中自定义loading加载效果,搭配nuxt/axios拦截器 -> 正文阅读

[JavaScript知识库]普歌-实测在Nuxt中自定义loading加载效果,搭配nuxt/axios拦截器

首先说一下我用的loading是一个第三方json动画库,底层用了window和document对象,在服务端会报错,只能在客户端跑。所以在服务端运行的请求钩子是不能进行loading效果的

先引入第三方动画库lottiefiles

  • 我的版本是^1.5.6
    npm install @lottiefiles/lottie-player

  • 在plugins下创建一个Loading文件夹,Loading下创建一个lottiePlayer.js全局引入该模块

// 引入lottiefiles
import '@lottiefiles/lottie-player'
  • 在nuxt.config.js中的plugins模块中引入
module.exports = {
  plugins: [
    // 自定义loading
    { src: '~/plugins/Loading/lottiePlayer.js', ssr: false }, // 使用了window对象,所以关闭服务端渲染
  ],
}

在plugins/Loading下创建一个loading.vue,并挂载到Vue实例原型上

  • Loading/loading.vue
<template>
  <div v-show="loading" class="loading-page">
    <lottie-player
      v-show="isShow"
      class="lottie"
      src="https://assets8.lottiefiles.com/packages/lf20_nm1huacl.json"
      background="transparent"
      speed="1.5"
      style="width: 300px; height: 300px"
      loop
      autoplay
    />
    <lottie-player
      v-show="!isShow"
      class="lottie"
      src="https://assets4.lottiefiles.com/private_files/lf30_weidduaf.json"
      background="transparent"
      speed="1"
      style="width: 300px; height: 300px"
      loop
      autoplay
    />
  </div>
</template>

<script>
export default {
  data: () => ({
    loading: false,
    // 随机展示两者中的一个
    isShow: Math.floor(Math.random() * 2)
  })
}
</script>

<style lang="less" scoped>
.loading-page {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  overflow: hidden;
  z-index: 99999;
  .lottie {
    position: absolute;
    top: 47%;
    left: 51%;
    transform: translate(-51%, -47%);
  }
  &::before {
    position: absolute;
    content: "";
    width: 100%;
    height: 100%;
    // background-color: #bebebe;
    background: rgba(235, 235, 235, 0.8);
    backdrop-filter: blur(5px);
    filter: Alpha(Opacity=90);
    opacity: 0.9;
  }
}
</style>

  • Loading/index.js 挂载
import Vue from 'vue'

// 自定义loading
import Loading from './loading.vue'
// 空实例
let instance = null

const loading = {
  install(Vue) {
    if (!instance) {
      // 构造器
      const MyLoading = Vue.extend(Loading)
      instance = new MyLoading({
        // 创建一个div,挂载上去
        el: document.createElement('div')
      })

      document.body.appendChild(instance.$el)
    }

    instance.loading = false // 默认为false

    // 自定义方法
    const customMethods = {
      start() {
        instance.loading = true
      },
      finish() {
        instance.loading = false
      }
    }

    // 挂载到自定义方法vue上
    if (!Vue.$loading) {
      Vue.$loading = customMethods
      // 挂载到原型上
      Vue.prototype.$loading = Vue.$loading
    } else {
      console.log('$loading方法被占用')
    }
  }
}
Vue.use(loading)
  • 然后在nuxt.config.js中的plugins注册一下,注意:要取消nuxt原来的loading效果,因为它原来在 n u x t 挂 载 的 也 是 nuxt挂载的也是 nuxtloading
//nuxt.config.js
export default {
	
  // 使用自定义loading,正好nuxt不用在this实例上添加$loading了
  loading: false,
  plugins: [
    // 自定义loading
    { src: '~/plugins/Loading/lottiePlayer.js', ssr: false }, // 使用了window对象
    { src: '~/plugins/Loading/index.js', ssr: false }, // 使用了document对象
  ],
}

在axios拦截器中添加loading

//api/interceptor.js
import Vue from 'vue'
import {
  message
} from 'ant-design-vue'

export default ({ store, route, redirect, $axios, req }) => {
  $axios.onRequest(config => {
    // 开启加载, 只有客户端才有window document 对象。配合plugins只在客户端中开启
    if (process.client) {
      Vue.prototype.$loading.start()
    }

    const accessToken = store.state.accessToken
    // 请求头添加token
    if (accessToken) {
      // Authorization: Bearer token
      config.headers.Authorization = `Bearer ${accessToken.replace(/"/g, '')}`
    }

    return config
  })

  $axios.onResponse(res => {
     // 客户端拦截打印   结束加载
    if (process.client) {
      console.log('客户端拦截数据:', res.data)
      setTimeout(() => {
        Vue.prototype.$loading.finish()
      }, 300)
    }
    if ((res.status !== 200 || res.data.code !== 20000) && process.client) {
      // !!! 服务端错误提示不生效,因为服务端没有document对象,所以在asyncData中请求的数据要注意!!!
      message.error(res.message || res.data.message || '数据响应异常', 1)
    }
    // 服务端不能执行message
    if (res?.data.code !== 20000 && process.server) {
      console.error('服务端:', res?.data.message || '数据响应异常')
      console.error('服务端错误数据:', res.data)
    }

    return res.data
  })

  $axios.onError(error => {
    // 结束加载, 只有客户端才有window document 对象。配合plugins只在客户端中开启
    if (process.client) {
      Vue.prototype.$loading.finish()
    }
    const { response: res } = error
    // 权限过期 -> 重定向
    if (res.status === 401 && res.data.code === 1401) {
      let isLock = true
      if (isLock && store.state.refreshToken) {
        isLock = false
        // 发送请求到认证客户端,通过刷新令牌获取新令牌
        redirect(`${process.env.authURL}/refresh?redirectURL=${redirectURL(route, req)}`)
      } else {
        isLock = true
        // 没有刷新令牌,跳转到登录页
        // 重置用户状态
        // console.log('跳转到登录页')
        store.commit('RESET_USER_STATE')
        // 跳转到登录页
        redirect(`${process.env.authURL}?redirectURL=${redirectURL(route, req)}`)
      }
      message.error(res.data.message, 1)
      if (process.client) {
        Vue.prototype.$loading.start()
      }
      return Promise.reject(res.data.message || 'Error')
    }
    message.error(res.data.message, 1)
    return Promise.reject('令牌过期,重新登录')
  })
}

// 获取重定向地址
const redirectURL = (route, req) => {
  // 客户端
  if (process.client) {
    return window.location.href
  }
  // 服务端
  return `${process.env.NODE_ENV === 'production' ? 'https://' : 'http://'}` + req.headers.host + route.fullPath
}

加载数据效果(在客户端请求数据时生效)
在这里插入图片描述
各位老板点赞三连


更多推荐:wantLG的《普歌-实测Nuxt坑,配置@nuxt/axios、拦截器、代理跨域,请求


  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-26 11:33:45  更:2022-04-26 11:34:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:11:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码