vue 如何实现 loading 读条,加载完成后显示页面? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
LeeReamond
V2EX    Vue.js

vue 如何实现 loading 读条,加载完成后显示页面?

  •  
  •   LeeReamond 2021-04-18 22:38:44 +08:00 6996 次点击
    这是一个创建于 1636 天前的主题,其中的信息可能已经有所发展或是发生改变。

    以前都是做单个组件的 axios 回调绑定加载完成事件,感觉还比较简单,现在想做一个全局读条,不会做了

    具体分为两个问题,其一是如何让用户在第一次打开页面时读一个条。比如用户第一次访问我的网站,而我的前端 spa 体积比较大,可能读个一两秒钟,这段时间我要在 vue 还没加载完成之前放一个 loading,然后等 vue 加载完成之后删掉这个 loading,没想好怎么做。

    其二是 vue 加载完成之后,单个路由页面的 loading,比如用户默认打开 index.html 之后,这时候 vue 的 js 已经在本地了,现在想跳转到 catalogue 页面,这个页面需要再额外加载若干图片和 css/js 脚本,我希望资源全部加载完成之前不要展示页面,这种应该怎么做呢?

    32 条回复    2021-04-20 00:41:23 +08:00
    mx8Y3o5w3M70LC4y
        1
    mx8Y3o5w3M70LC4y  
       2021-04-18 22:42:56 +08:00 via Android
    useEffect
    joesonw
        2
    joesonw  
       2021-04-18 23:29:08 +08:00 via iPhone
    纯 html 放 loadong,加载完后再干掉。
    freak118
        4
    freak118  
       2021-04-18 23:57:18 +08:00
    @lvdb 能详细说说吗
    ch2
        5
    ch2  
       2021-04-19 00:18:20 +08:00 via iPhone
    在首屏的那个 html 里做 loading,等 js 啥的加载完了再让它消失
    LeeReamond
        6
    LeeReamond  
    OP
       2021-04-19 01:29:05 +08:00
    @ch2
    @joesonw
    思路是这么个思路,但是具体操作怎么做呢,是类似让 vue 搜索 loading 的 id 然后干掉这个 element 么。

    另外一个问题是 vue 怎么知道自己加载完成了,因为我用 vuetify 模板,还需要引入一些 google 字体和图标 css 之类的,可能还有图片
    LeeRamond
        7
    LeeReamond  
    OP
       2021-04-19 01:56:46 +08:00
    @LeeReamond 试了一下往 index.html 里加东西。。结果变成不管哪个路由都会先闪过一下 loading 画面,感觉不太好
    kmore
        8
    kmore  
       2021-04-19 08:07:38 +08:00 via iPhone
    vue 生命周期函数 beforeCreate 实例初始化加入 loading,created 实例创建完成结束 loading,全局写个 mixin
    yesC
        9
    yesC  
       2021-04-19 08:55:18 +08:00
    如果用到 vue-router 的话可以看看路由守卫,可以配合组件 nprogress,这个效果和你说的需求很相似,可以参照着改改。
    WEBUG
        10
    WEBUG  
       2021-04-19 08:56:49 +08:00
    @LeeReamond 初次加载的 loading 写在 index.html 里面,写一个内部 css,在 index 最下方写 js 方法干掉 css 。其他阶段的 loading 就写在 vue 里面了。
    plk403
        11
    plk403  
       2021-04-19 09:00:46 +08:00
    我也有一个问题,怎样让当前路由的图片全部加载完之前显示 loading 呢? ? ? 就是判断图片全部加载完毕再显示页面...给跪了
    lh900519
        12
    lh900519  
       2021-04-19 09:05:48 +08:00 via Android
    @LeeReamond 把 loading 的代码放到#app 元素里面,vue 开始渲染的时候,会把#app 里面的元素给替换掉
    iplayio2019
        13
    iplayio2019  
       2021-04-19 09:16:04 +08:00 via Android
    我以前这么写过,写一个 loading 全局计数器,开始请求计数器加 1,请求完成计数器减 1,百分比增加百分 20,如果百分比小于 80%,直到计数器为 0 。
    cyrbuzz
        14
    cyrbuzz  
       2021-04-19 09:46:05 +08:00
    还有一个思路是用 SSR,Nuxt 里写 layout,这样就可以完全使用 Vue 的生命周期。
    cereschen
        15
    cereschen  
       2021-04-19 10:38:24 +08:00
    都没说到点子上去 用异步组件 请阅读文档
    2kCS5c0b0ITXE5k2
        16
    2kCS5c0b0ITXE5k2  
       2021-04-19 11:08:26 +08:00   1
    v-cloak?
    pouta
        17
    pouta  
       2021-04-19 11:13:35 +08:00
    看官方文档,全局路由守卫
    GenericClass
        18
    GenericClass  
       2021-04-19 11:15:19 +08:00
    zhuweiyou
        19
    zhuweiyou  
       2021-04-19 11:40:45 +08:00
    直接在 public/index.html 里面写 loading show
    cereschen
        20
    cereschen  
       2021-04-19 12:08:49 +08:00   1
    我觉得直接说去看文档 确实有些不够负责任
    我这里给出了示例代码 组件的加载完全由自己掌握

    export default new Router({
    routes: [
    {
    path: '/',
    name: 'start-page',
    component: () => ({
    // 需要加载的组件 (应该是一个 `Promise` 对象)
    component: new Promise(r => {
    setTimeout(() => {
    r(import('@/views/start'))
    }, 2000);
    }),
    // 异步组件加载时使用的组件
    loading: {
    render(h) {
    h('div', 'loading.....')
    }
    },
    // 加载失败时使用的组件
    error: {
    render(h) {
    h('div', 'error.....')
    }
    },
    // 展示加载时组件的延时时间。默认值是 200 (毫秒)
    delay: 5000,
    // 如果提供了超时时间且组件加载也超时了,
    // 则使用加载失败时使用的组件。默认值是:`Infinity`
    timeout: 30000
    })
    }]
    })
    hm20062006ok
        21
    hm20062006ok  
       2021-04-19 13:48:06 +08:00   1
    第一个问题, 如果“用户第一次访问我的网站”打开的是首页。下面有一个效果:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" cOntent="IE=edge,chrome=1">
    <meta name="renderer" cOntent="webkit">

    <title>WebSiteName</title>
    <style type="text/css">body {
    margin: 0;
    padding: 0
    }

    .loading {
    width: 100%;
    height: 100%;
    background: #fff;
    position: absolute
    }

    .lodingco {
    width: 200px;
    height: 80px;
    text-align: center;
    z-index: 1;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto
    }

    .loading h2 {
    color: #666;
    margin: 0;
    text-transform: uppercase;
    letter-spacing: .1em;
    font-size: 20px;
    font-weight: 400;
    font-family: cursive
    }

    .loading span {
    display: inline-block;
    vertical-align: middle;
    width: .6em;
    height: .6em;
    margin: .19em;
    background: #007DB6;
    border-radius: .6em;
    -webkit-animation: loading 1s infinite alternate;
    animation: loading 1s infinite alternate;
    animation: loading 1s infinite alternate
    }

    .loading span:nth-of-type(2) {
    background: #008FB2;
    -webkit-animation-delay: .2s;
    animation-delay: .2s
    }

    .loading span:nth-of-type(3) {
    background: #009B9E;
    -webkit-animation-delay: .4s;
    animation-delay: .4s
    }

    .loading span:nth-of-type(4) {
    background: #00A77D;
    -webkit-animation-delay: .6s;
    animation-delay: .6s
    }

    .loading span:nth-of-type(5) {
    background: #00B247;
    -webkit-animation-delay: .8s;
    animation-delay: .8s
    }

    .loading span:nth-of-type(6) {
    background: #5AB027;
    -webkit-animation-delay: 1s;
    animation-delay: 1s
    }

    .loading span:nth-of-type(7) {
    background: #A0B61E;
    -webkit-animation-delay: 1.2s;;
    animation-delay: 1.2s
    }

    @-webkit-keyframes loading {
    0% {
    opactty: 0
    }
    100% {
    opacity: 1
    }
    }

    @keyframes loading {
    0% {
    opacity: 0
    }
    100% {
    opacity: 1;
    }
    }</style>
    </head>
    <body>

    <div id="app">
    <div class="loading">
    <div class="lodingco"><h2>WebSiteName Loading</h2>
    <span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div>
    </div>
    </div>

    </body>


    </script>
    </html>
    joesonw
        22
    joesonw  
       2021-04-19 13:56:08 +08:00
    @LeeReamond js 加载完后, 加载 img 的时候加一个 onload, 手动计数.
    rozbo
        23
    rozbo  
       2021-04-19 14:16:19 +08:00
    slert
        24
    slert  
       2021-04-19 14:58:57 +08:00
    nuxt 的 spa 模式就自带这个效果
    ToPoGE
        25
    ToPoGE  
       2021-04-19 16:55:09 +08:00
    在 index.html 的里写加载样式,
    在 index.html 里写 window.onload 事件,取消加载样式
    你在 vue 里写的加载,只能用于 vue.js 载入完成后才生效,不然之前就是白屏
    其实说白了就是 index.html 加载完成,但是你 vue 及相关库没载入完成,之间的 loading 效果
    LeeReamond
        26
    LeeReamond  
    OP
       2021-04-19 18:56:14 +08:00
    @ToPoGE 感觉可以操作,大佬请教一下 onload 怎么理解,它这个加载完成,是指 vue 将 dom 渲染完,还是说文件下载到本地( vue 还没执行 create 之前)就已经触发 onload 了?如果 vue 中又添加了新的依赖,应该怎么理解呢,比如下载了 vue 的文件,然后 vue 又要求某个 css,onload 会触发两次么
    Q4h7388nR28s95fa
        27
    Q4h7388nR28s95fa  
       2021-04-19 20:19:48 +08:00
    这两个问题凑一起真是绝了!

    https://v2ex.com/t/771311#reply23

    楼主先把最基础的 html 和 js 学好了,这个问题就不是问题了。
    LeeReamond
        28
    LeeReamond  
    OP
       2021-04-19 21:19:55 +08:00
    @HiCode 无非讨论一些实现上的惯例,我觉得跟学没学好基础没什么关系,而且本来前端也比较随意。看你的回复是觉得太简单了不屑于讨论这类问题?
    Q4h7388nR28s95fa
        29
    Q4h7388nR28s95fa  
       2021-04-19 23:49:05 +08:00
    @LeeReamond 真有趣,等你基础补好了,你回头再看看你上面给其他人的回复,就知道我为什么会说是基础的问题。

    这不是屑不屑的问题,而是说答案就在那里,有些人直接往答案的方向走,有些人选择 v2 上提问,前者事半功倍,后者事倍功半。

    没有说哪种对哪种错,时间是自己的,开心就好!
    LeeReamond
        30
    LeeReamond  
    OP
       2021-04-20 00:06:45 +08:00
    @rozbo 大佬,你这个方案我试了一下,在本地 dev 调试的话,每次刷新任何界面都会闪过 loading 界面,build 之后上传到远端以后反而不会了,大佬能讲下啥原因么
    LeeReamond
        31
    LeeReamond  
    OP
       2021-04-20 00:10:06 +08:00
    @HiCode 确实挺有趣的,可能不是技术的问题,应该只是单纯的阅读理解问题。至于你说的上面其他人的回复,楼上提的 nprogress,路由守卫自定义,和 vue 接管前插入几个方案我都试了,没有找到特别完美的解决方案,我倒不是很懂你说的补好基础再回来看指看什么。
    Q4h7388nR28s95fa
        32
    Q4h7388nR28s95fa  
       2021-04-20 00:41:23 +08:00
    第 5 楼:“思路是这么个思路,但是具体操作怎么做呢,是类似让 vue 搜索 loading 的 id 然后干掉这个 element 么。”

    直接通过 dom 接口查找 loading 响应的节点,删掉,跟 vue 没关系,找个基本的 HTML DOM 教程看一下,最基本的就行。这个都可以说没有思路,感觉就不是做前端的了。

    第 21 楼:“感觉可以操作,大佬请教一下 onload 怎么理解,它这个加载完成,是指 vue 将 dom 渲染完,还是说文件下载到本地( vue 还没执行 create 之前)就已经触发 onload 了?如果 vue 中又添加了新的依赖,应该怎么理解呢,比如下载了 vue 的文件,然后 vue 又要求某个 css,onload 会触发两次么”

    他说的是“ window.onload ”,window 对象的 onload 事件,看 dom 教程吧……


    看 dom 教程吧……
    看 dom 教程吧……
    看 dom 教程吧……
    看 dom 教程吧……
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5327 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 55ms UTC 09:14 PVG 17:14 LAX 02:14 JFK 05:14
    Do have faith in what you're doing.
    ubao 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