Vue 2 进度提示完整代码

 

一、排查常见失效原因(核心问题)

大概率是这几个原因: 
  1. 延迟设置(默认 300ms):如果请求耗时短于 300ms,加载提示会被跳过(避免闪烁),测试时需模拟长请求;
  2. DOM 挂载失败:loading 实例未正确添加到 body,或路径引入错误;
  3. 样式层级问题:z-index 不够,被页面元素遮挡;
  4. 调用时机错误hideLoading 调用过早,或未在 finally 中执行;
  5. 文件路径错误:Loading 组件 / 工具函数的引入路径写错。

二、方案(简化版,无延迟,优先确保显示)

1. Loading 组件(src/components/Loading.vue

去掉延迟逻辑,提高样式层级,确保肉眼可见:
 
vue 
<template>
  <div class="loading-container" v-if="isShow">
    <!-- 遮罩层:浅背景更容易看到 -->
    <div class="loading-mask"></div>
    <!-- 加载内容:居中显示 -->
    <div class="loading-content">
      <div class="loading-spinner"></div>
      <p class="loading-text">{{ text }}</p>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Loading',
  props: {
    // 是否显示(直接控制,无延迟)
    isShow: {
      type: Boolean,
      default: false
    },
    // 提示文字
    text: {
      type: String,
      default: '加载中...'
    }
  }
}
</script>

<style scoped>
/* 核心:提高z-index到99999,避免被遮挡 */
.loading-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 99999; /* 远高于普通元素 */
  display: flex;
  justify-content: center;
  align-items: center;
}

/* 浅白色遮罩,确保加载框显眼 */
.loading-mask {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(255, 255, 255, 0.8);
}

/* 加载框样式:白色背景+阴影 */
.loading-content {
  background-color: #fff;
  padding: 20px 30px;
  border-radius: 8px;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
  text-align: center;
}

/* 旋转加载图标(确保动画生效) */
.loading-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #f0f0f0;
  border-top: 4px solid #42b983; /* Vue 绿色,显眼 */
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin: 0 auto 10px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.loading-text {
  color: #333;
  font-size: 14px;
  margin: 0;
}
</style>
 

2. 加载工具函数(src/utils/loading.js

简化逻辑,确保实例正确挂载到 body:
 
javascript
import Vue from 'vue'
import Loading from '../components/Loading.vue' // 确认路径正确!

// 创建组件构造器
const LoadingConstructor = Vue.extend(Loading)
let loadingInstance = null // 存储唯一实例

// 显示加载提示
export const showLoading = (options = {}) => {
  // 先销毁已有实例,避免重复显示
  if (loadingInstance) {
    hideLoading()
  }

  // 创建实例并挂载(生成$el)
  loadingInstance = new LoadingConstructor({
    propsData: {
      isShow: true,
      text: options.text || '加载中...'
    }
  }).$mount() // 挂载但不指定节点,手动添加到DOM

  // 强制添加到body(关键:确保DOM存在)
  document.body.appendChild(loadingInstance.$el)
  // 手动触发更新,避免渲染延迟
  loadingInstance.$forceUpdate()
}

// 隐藏加载提示
export const hideLoading = () => {
  if (loadingInstance) {
    // 直接隐藏
    loadingInstance.isShow = false
    // 移除DOM并销毁实例
    setTimeout(() => {
      if (loadingInstance && loadingInstance.$el) {
        document.body.removeChild(loadingInstance.$el)
      }
      loadingInstance = null // 重置实例
    }, 100)
  }
}

// 注册到Vue原型,全局可用
Vue.prototype.$showLoading = showLoading
Vue.prototype.$hideLoading = hideLoading
 

3. 确认 main.js 引入(路径必须正确)

javascript
 
import Vue from 'vue'
import App from './App.vue'
import router from './router'

// 引入加载工具(确认路径:src/utils/loading.js)
import './utils/loading'

Vue.config.productionTip = false

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')
 

三、快速验证(必做!确保能看到加载提示)

创建测试页面(src/views/TestLoading.vue),模拟 5 秒长请求,确保加载提示显示:
 
vue 
<template>
  <div >
    <h2>测试加载提示</h2>
    <!-- 点击按钮触发长请求 -->
    <button @click="triggerLongRequest" >
      点击触发5秒长请求
    </button>
  </div>
</template>

<script>
export default {
  name: 'TestLoading',
  methods: {
    async triggerLongRequest() {
      // 1. 立即显示加载提示(无延迟)
      this.$showLoading({ text: '正在加载大数据...' })
      
      try {
        // 2. 模拟5秒长请求(足够看到加载提示)
        await new Promise(resolve => setTimeout(resolve, 5000))
        alert('加载完成!')
      } catch (error) {
        alert('加载失败!')
      } finally {
        // 3. 无论成功/失败,都隐藏提示
        this.$hideLoading()
      }
    }
  }
}

 

posted @ 2025-12-06 08:39  emanlee  阅读(0)  评论(0)    收藏  举报