V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Kawa
V2EX  ›  Vue.js

Vue 3 的服务端与异步数据获取

  •  
  •   Kawa · 2022-04-08 20:38:22 +08:00 · 1719 次点击
    这是一个创建于 739 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近项目才上线, 打算修一下 SSR 半残的状态. 以下内容是根据实践得出的结论, 不过我还是有点迷糊, 所以分享出来给大家看一下, 如果有错误或者有什么想法可以在下面指正.

    内容基于使用 setup script 的情况.

    几个基本点:

    1. SSR 渲染时, 生命周期钩子里只有 beforeCreate 和 created 会被触发. 意味着你不能在其他钩子里执行获取数据的逻辑.
    2. SSR 渲染时, 响应式变量不会被触发更新, 渲染状态以逻辑执行时的数据为准. 意味着如果你使用空数据占位, 等到数据到达时更新数据的做法会在 SSR 时失效.

    几个建议:

    1. 如果你在用响应式变量控制组件的加载状态(isLoading), 替换成Suspense和 Async Setup. 因为isLoading不会触发组件更新, 最后即便你获取到了数据仍然可能渲染出一个骨架屏.
    2. 不要通过监听响应式变量的值变化来控制 Async Function 的挂起状态. 同样是出于响应式变量不会更新的原因, 使用响应式变量挂起和恢复 Async Function 不会起作用, 如果以这种方式去控制 Async Setup, 那么就会导致渲染死锁, 而且如果没有经验, 你几乎难以找到死锁的原因, 因为这样做在客户端是能够正常工作的, 但是在服务端是不行的.
    3. 如果你想往子组件里 Provide 你的异步数据, 请使用注入一个Ref<Promise<T>>, 而不是Ref<T | undefined>, 通过 Promise, 同样还是因为响应式变量不会触发更新, 你只能通过注入 Promise 并 await 他以挂起 setup 函数, 以确保组件被渲染时数据不为空.
    第 1 条附言  ·  2022-05-04 01:09:03 +08:00
    如果你收藏了本帖子, 请注意:
    经过排查, 我发现某些奇奇怪怪的 bug 是因为我使用了一个 denounced Ref 所导致的. 帖子里的内容不完全正确, 但是可以用来作为解决问题的参考思路.
    关于这个疏漏的细节已经差不多忘记了, 拖了很久才想起来在这里发过这个帖子.
    共勉
    3 条回复    2022-04-20 17:53:30 +08:00
    duan602728596
        1
    duan602728596  
       2022-04-08 21:06:59 +08:00
    SSR 时,一部分的数据(比如首屏加载的数据)是从后端获取的。
    输出 html 的同时也会输出 initialData ,比如 b 站会有 window.__INITIAL_DATA__,为了保证数据的一致性,渲染不会出现差异。
    通过 ajax 获取的数据本来就没有必要在后端提前获取数据,所以什么都不输出或者只渲染个骨架屏是正确的做法。
    Kawa
        2
    Kawa  
    OP
       2022-04-08 22:26:09 +08:00
    @duan602728596
    我做的是完全的单页应用, 所有数据都应该从后端获取.
    但是这样做就非常的 SEO 不友好, 这样就得在 SSR 期间把这些数据渲染上去.
    这就是你所说的 initialData.

    但是你貌似没有考虑 initialData 从哪来. 对于完全的单页应用, 所有数据只能通过 API 获取, 那么我就需要考虑怎么去把这些数据搞到手并渲染出来.

    我想的方案就是直接复用客户端的逻辑, 然后塞入 SSR 特有逻辑将数据打包与渲染好的内容一同发给客户端.
    这种方案是我目前想到的实现成本比较低的方案, 可以直接复用客户端的逻辑获取数据.

    目前还没想到实现成本更低的方案, 如果你有什么想法可以说来听听.
    KouShuiYu
        3
    KouShuiYu  
       2022-04-20 17:53:30 +08:00
    我之前的做法是按照单页应用开发,用 node 特殊处理在首页需要注入的初始变量,比如 window.__INITIAL_DATA__= 。。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   992 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 20:13 · PVG 04:13 · LAX 13:13 · JFK 16:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.