V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
coollest
V2EX  ›  程序员

VUE3,页面加了 keepAlive 之后 table 组件的 v-loading 失效

  •  
  •   coollest · 2 天前 · 716 次点击

    App.vue 里边的代码是

    <el-main class="container">
    	<router-view v-slot="{ Component }">
    		<keep-alive v-if="$route.meta.keepAlive">
    			<component :is="Component" :key="$route.path"  />
    		</keep-alive>
    		<component :is="Component" :key="$route.path" v-else/>
    	</router-view> 
    </el-main>
    

    页面中只在 table 组件上加了 v-loading ,请求数据前设置为 true ,得到数据后为 false 。现在的问题是第一次进

    入页面加载数据时,table 会直接显示 no data ,而不是 loading 转圈。各位大佬有遇到过这个问题吗,求教。

    第 1 条附言  ·  1 天前

    最后问题解决了用的是服务的方式调用v-loading

    import { ElLoading } from 'element-plus'
    // 取数据之前调用
    const loadingInstance = ElLoading.service({fullscreen: true})
    // 结束时关闭
    loadingInstance.close()
    
    10 条回复    2024-09-27 13:13:06 +08:00
    Happy66606
        1
    Happy66606  
       2 天前
    这是因为 `keep-alive` 缓存了组件的状态,当你再次进入页面时,组件不会被重新渲染,而是直接从缓存中取出之前的状态。因此,`v-loading` 的状态也不会被重新设置。

    你可以尝试在组件的 `activated` 生命周期钩子中手动设置 `v-loading` 的状态。例如:

    ```javascript
    activated() {
    this.loading = true;
    // ... 请求数据 ...
    }
    ```

    或者,你可以使用 `keep-alive` 的 `include` 属性来排除某些组件不被缓存。例如:

    ```html
    <keep-alive :include="['Home', 'About']">
    <!-- ... -->
    </keep-alive>
    ```

    这样,`table` 组件就不会被缓存,`v-loading` 的状态就会被正常设置。

    另外,你也可以尝试使用 `v-if` 来控制 `table` 组件的渲染,例如:

    ```html
    <table v-if="!loading" v-loading="loading">
    <!-- ... -->
    </table>
    ```

    这样,当 `loading` 为 `true` 时,`table` 组件就不会被渲染。
    coollest
        2
    coollest  
    OP
       2 天前
    @Happy66606 感谢大佬,我试了一下 activated 钩子的方法,好像还是不太行啊,就是请求完一次数据之后,组件被缓存,第二次进入也没有 loading 的这个问题。现在就是第一次进入页面,v-loading 还是不生效。再次感谢!我再自己研究一下
    fishlium
        3
    fishlium  
       2 天前
    你的数据加载写在什么地方的
    coollest
        4
    coollest  
    OP
       2 天前
    @fishlium 写在 onBeforeMount 钩子里的
    fishlium
        5
    fishlium  
       2 天前
    @coollest 你写 onMounted()的试试
    coollest
        6
    coollest  
    OP
       1 天前
    @fishlium 昨晚忘了回复了,还是不行。但是还是谢谢大佬!
    fishlium
        7
    fishlium  
       1 天前
    @coollest 你把 v-if 换到 component 上试试呢
    coollest
        8
    coollest  
    OP
       1 天前
    @fishlium 昨晚发现这个问题了,如果按照帖子里的写法 keepAlive 就直接失效了,放在 component 上才能正常生效。但是还是没有 loading 的效果
    0xD800
        9
    0xD800  
       1 天前
    有复现 demo 吗 用 setTimeout 模拟数据请求
    coollest
        10
    coollest  
    OP
       1 天前
    @0xD800 差不多是这样的

    <script lang="ts" setup>
    import axios from 'axios';
    import { ElLoading } from 'element-plus'
    import { onMounted } from 'vue';
    let loadingInstance:any = null

    function getData() {
    let res:any = axios.post('xxx')
    if (res && res.success) {
    loadingInstance.close()
    } else {
    //报错提示
    loadingInstance.close()
    }
    }
    onMounted(() => {
    loadingInstance = ElLoading.service({fullscreen: true})
    //请求数据
    getData()
    })
    </script>
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2296 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 15:35 · PVG 23:35 · LAX 08:35 · JFK 11:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.