手把手带你实现vue全屏loading插件

x33g5p2x  于2021-10-09 转载在 Vue.js  
字(2.9k)|赞(0)|评价(0)|浏览(622)

功能分析

vue项目中所有的请求一般都是通过axios,所以我们需要给axios新增请求和响应拦截,在请求拦截中显示loading,和响应拦截中关闭loading。

所以我们需要定义两个全局方法,一个是显示loading,叫s h o w L o a d i n g ( ) , 另 一 个 叫 showLoading(),另一个叫showLoading(),另一个叫hideLoading()关闭全屏loading。

代码实现

上面的梳理,我们明确了,需要定义两个全局方法,一个显示loading一个关闭loading,这里我们定义一个Vue的插件通过插件动态给实例安装 显示和关闭Loading方法。

定义$loading插件,在Vue构造函数原型上添加两个方法

以下loading.js代码

  1. const $loading = {
  2. install: (Vue) => {
  3. // 添加 显示loading方法
  4. Vue.prototype.$showLoading = () => {
  5. console.log('loading显示')
  6. }
  7. // 添加关闭loading方法
  8. Vue.prototype.$hideLoading = () => {
  9. console.log('loading关闭')
  10. }
  11. }
  12. }
  13. export default $loading;
  14. // 使用时,在main.js入口函数中引入,使用插件即可安装
  15. Vue.use($loading)

添加axios请求和相应拦截,调用显示和关闭loading方法

  1. import Vue from 'vue';
  2. // 定义Vue实例 调用全局显示和关闭loading方法
  3. const vm = new Vue();
  4. // 请求拦截
  5. axios.interceptors.request.use(function(config) {
  6. // 调用loading方法
  7. vm.$showLoading()
  8. return config
  9. }, function(error) {
  10. // 在请求出错调用 关闭loading方法
  11. vm.$hideLoading()
  12. return Promise.reject(error)
  13. })
  14. // 相应拦截
  15. axios.interceptors.response.use(function(response) {
  16. vm.$hideLoading()
  17. return response
  18. }, function(error) {
  19. vm.$hideLoading()
  20. return Promise.reject(error)
  21. })

当然我们 在数据请求不是打印,而是 显示loading,数据过来时应该关闭loading,所以接下来我们实现这两个效果

通过单文件组件 定义显示loading结构
我们目前的问题是,在显示loading时不是打印而是要显示全局loading的html结构,在关闭loading时要隐藏!

为了实现这个需求,我们通过vue的单文件组件来定义loading的html结构和控制loading显示隐藏

loading.vue
  1. <template>
  2. // mask是loading的背景 v-show控制loading显示或消失
  3. <div class="mask" v-show="isShow"></div>
  4. <div class="loading"></div>
  5. </template>
  6. <script>
  7. export default {
  8. return {
  9. isShow: false // 默认不显示
  10. }
  11. }
  12. </script>
  13. <style lang="scss">
  14. // 定义动画 控制loading旋转
  15. @keyframes rotate {
  16. 0% {
  17. transform: rotate(0deg);
  18. }
  19. 100% {
  20. transform: rotate(360deg);
  21. }
  22. }
  23. .mask {
  24. position: fixed;
  25. left: 0;
  26. right: 0;
  27. top: 0;
  28. bottom: 0;
  29. background-color: rgba(0, 0, 0, .7);
  30. z-index: 10000;
  31. display: flex;
  32. align-items: center;
  33. justify-content: center;
  34. .loading {
  35. width: 30px;
  36. height: 30px;
  37. border: 6px solid rgb(219, 140, 13);
  38. border-radius: 21px;
  39. border-left-color: transparent;
  40. animation: rotate 500ms infinite;
  41. }
  42. }
  43. </style>

loading.js中获取单文件组件 html结构 并在 s h o w L o a d i n g 方 法 调 用 时 显 示 , 在 showLoading方法调用时显示,在showLoading方法调用时显示,在hideLoading时隐藏

  1. // loading.js中
  2. import LoadingVue from './loading.vue';
  3. const $loading = {
  4. install: (Vue) => {
  5. // 通过Vue.extend方法 获取LoadingComponent 组件类
  6. const LoadingComponent = Vue.extend(LoadingVue);
  7. // new LoadingComponent得到组件的实例
  8. const vm = new LoadingComponent();
  9. // 获取组件实例的html 并插入到body中
  10. const tpl = vm.$mount().$el;
  11. // 插入到body中
  12. document.body.appendChild(tpl);
  13. // 添加 显示loading方法
  14. Vue.prototype.$showLoading = () => {
  15. // 通过改变实例 .mask v-show绑定变量控制显示
  16. vm.isShow = true
  17. }
  18. // 添加关闭loading方法
  19. Vue.prototype.$hideLoading = () => {
  20. // 通过改变实例 .mask v-show绑定变量控制隐藏
  21. vm.isShow = false
  22. }
  23. }
  24. }

最后在main.js中使用插件 在axios拦截器中控制显示隐藏就ok啦!!

  1. // main.js
  2. import Vue from 'vue';
  3. import loading from './plugins/loading';
  4. Vue.use(loading)

axios 拦截器中使用

  1. import Vue from 'vue';
  2. const vm = new Vue();
  3. axios.interceptors.request.use(config => {
  4. vm.$showLoaing()
  5. return config
  6. }, error => {
  7. vm.$hideLoading()
  8. return Promise.reject(error)
  9. })
  10. // 响应拦截
  11. axios.interceptors.response.use(config => {
  12. vm.$hideLoading()
  13. return response
  14. }, error => {
  15. vm.$hideLoading()
  16. return Promise.reject(error)
  17. })

相关文章

最新文章

更多