还是 Vue loading 过场的疑问? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
elboble
V2EX    Vue.js

还是 Vue loading 过场的疑问?

  •  
  •   elboble 2023-03-17 11:49:34 +08:00 3151 次点击

    原来登录界面没有等待的过场傻等,后来学习大家的都有个 Loading 或者 Checking 的过场,就用 v-if 加了。登录请求后台返回后就取消 loading ,成功了就跳转业务页面,失败就重新登录,逻辑上很简单没啥问题。

    但是跑起来发现个问题,跳转的业务页面需要资源比较多,第一次加载要个 1-2 秒,这时候会即使成功了先跳出登录界面 1-2 秒,再被业务页面覆盖,这就有点尴尬。

    我现在的办法是如果登录成功,就不改 loading 了,一直转到业务页面加载出来。登录失败才改 loading 。 这个是不是不太优雅。

    没进过厂,想请教这个小问题是怎么处理的?

    <template> <div> <div v-if="isLoading"> <LoadingSpinner /> </div> <div v-else> //登录页面 .... </div> </div> ... </template> <script lang="ts"> .... const setup(){ const btnClick = () => { if (username.value && password.value) { authStore.returnUrl = route.query.redirect; isLoading.value = true; authStore .login(username.value, password.value) .then((ret) => { if (ret !== 0) { message.warning("账号或密码错误。"); **isLoading.value = false; //现在在这里** } else { message.success("登录成功"); router.push((route.query.redirect as LocationQueryValue) || "/"); } }) .catch((err) => { console.error(err); }) .finally(() => { **// isLoading.value = false; //原来在这里** }); } else { message.warning("请输入用户名和密码。"); } }; } .... </script> 
    16 条回复    2023-03-18 12:17:58 +08:00
    op351
        1
    op351  
       2023-03-17 11:53:50 +08:00
    ```
    这时候会即使成功了先跳出登录界面 1-2 秒,再被业务页面覆盖,这就有点尴尬。
    ```
    这句话什么意思?
    molvqingtai
        2
    molvqingtai  
       2023-03-17 11:57:23 +08:00
    同问
    hervey0424
        3
    hervey0424  
       2023-03-17 12:00:52 +08:00   1
    登录按钮上就 loading, 登录失败了取消, 成功了直接跳转到业务页面
    Huelse
        4
    Huelse  
       2023-03-17 12:04:06 +08:00
    两种方案:
    1 、Loading 为顶层覆盖
    2 、Loading 放在 v-else ,需要显示的内容为 v-if="data && !loading"
    elboble
        5
    elboble  
    OP
       2023-03-17 12:05:47 +08:00
    @op351 我也不太清楚,我是这样分析的,开始 isLoading.value = false 是在 finally 里,这样后端登录校验返回后,无论正确错误,isLoading 都会 false 。如果正确,应该 router.push 到业务界面了,但是因为业务界面加载时间长,或者其他原因比较慢,会进 v-else ,就是又出现了登录界面。

    所以后来我把 isLoading.value = false 只放到登录失败的情况里,如果正确自然就不会进 v-else 了。

    对了,这是个单页面应用。
    molvqingtai
        6
    molvqingtai  
       2023-03-17 12:11:50 +08:00
    从代码可以看出登录交互有问题,登录页面 loading 时也应该一直存在,loading 可以弹个 toast loading 或者 button loading ,未避免接口响应太快,导致 loading 动画闪一下有个巧妙的解决办法:

    const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

    await Promise.allSettled([sleep(1000), login()]);
    // loading 结束跳转到首页
    op351
        7
    op351  
       2023-03-17 12:24:04 +08:00   1
    @elboble
    所以你的问题是 使用 router.push 跳转到下一个页面的过程中 如何处理上一个页面仍然残留的问题
    参考这个链接吧
    https://router.vuejs.org/zh/guide/advanced/navigation-failures.html
    3282361
        8
    3282361  
       2023-03-17 14:30:50 +08:00
    这好像应该用 <Suspense>
    subframe75361
        9
    subframe75361  
       2023-03-17 17:55:48 +08:00
    用异步组件?
    djkloop
        10
    djkloop  
       2023-03-17 18:32:54 +08:00
    弄个 store... 在下个页面干掉...你这情况让我想起了 vben 那个后台...登录成功了但是 其实下个页面的资源还在加载...一般页面路由是懒加载...要不然笨办法把首页不要懒加载
    lscho
        11
    lscho  
       2023-03-17 18:42:28 +08:00
    楼上正解,你的 loading 其实是两个页面的状态,第一个是登录页面的请求等待状态,第二个是登录成功跳转目标页面资源加载、数据初始化的状态。你的做法只解决了第一个登录页面的请求等待状态,但是第二个页面的初始化状态没有解决。

    所以把 loading 提出来放到全局 store 中,点击登录按钮时开始 loading ,直到第二个页面加载完再结束 loading
    billly
        12
    billly  
       2023-03-17 19:00:10 +08:00
    业务页面再加个 loading
    cyrbuzz
        13
    cyrbuzz  
       2023-03-17 19:05:19 +08:00
    感觉你这个直接把 v-if="isLoading"扩展成 v-if="isLoading || isLogin"就完事了。

    分析下来你的 loading 仅处理了是不是完成了登录 API 的调用,完全没什么问题,逻辑紧密也很容易理解。

    理想情况下 loading 完之后应该立即跳转到下一个页面,不应该在当前页面停留,但因为某些原因导致仍然会在此页面停留一段时间,就导致了问题。

    顺着这条路解决思路就是:
    1. 在继续停留的这段时间内仍然保持 loading 状态(做法如前所说,loading 的判断变成是否处在 API 调用中或者是否已经登录,或者楼上说的在下个页面处理(= =不太推荐,这样逻辑太撕裂了))。
    2. 专门做一下路由切换的过渡动画,这个 Vue 开箱即用,https://router.vuejs.org/zh/guide/advanced/transitions.html
    3. 预(懒)加载一些资源(楼上说的异步组件),让将要去的页面尽快显示出来。

    如果是我的话= =,通用性强的方法就是 2+3 一起做,实际上也应该是项目中应该做到的事情(ToC),省事就 1 咯。
    WilliamLin
        14
    WilliamLin  
       2023-03-18 10:10:39 +08:00 via iPhone
    @lscho 同感
    elboble
        15
    elboble  
    OP
       2023-03-18 11:32:55 +08:00
    @lscho @cyrbuzz @molvqingtai @op351 @djkloop @Huelse @hervey0424 感谢各位。
    现在没用单独的 loading 界面,直接用带 loading 的按钮,这样登录界面不消失,就需要在 isloading 中 disable input 和 button 了,界面没闪,问题没那么明显。

    关键问题是业务页面加载慢的问题,按道理应该是业务页面加载也要有 loading 过场。
    不过暂时就用登录正确就不切换 isloading 状态了,直接等业务页面加载出来,最简单。

    transition 还在学习中。

    这么个基本的交互,前端都有这么多坑,按道理要求应该很高,不至于像 V 上说的这么卷吧。
    LykorisR
        16
    LykorisR  
       2023-03-18 12:17:58 +08:00
    可以嵌套一层,loading 在父组件,然后 login 和业务的子组件更新父组件的状态
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4890 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 05:39 PVG 13:39 LAX 22:39 JFK 01:39
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86