解决 SSR 框架的布局不一致思路

首先使用项目实例,介绍需求和遇到的问题

使用Nuxt的时候常常会遇到潜在的闪烁 / 布局不一致

平台:Nuxt

包文件: Splitpanes

xml 复制代码
​
<script setup lang="ts">
// @ts-expect-error missing type
import { Pane, Splitpanes } from 'splitpanes'
​
const ui = useUiState()
const play = usePlaygroundStore()
</script>
​
<template>
  <Splitpanes
  >
    <Pane :size="ui.panelDocs" min-size="10">
      <PanelDocs />
    </Pane>
    <Pane :size="100 - ui.panelDocs">
      <Splitpanes
        horizontal
      >
        <Pane :size="ui.panelEditor" min-size="10">
          <PanelEditor :files="play?.files" />
        </Pane>
        <Pane :size="ui.panelPreview" min-size="10">
          <PanelPreview />
        </Pane>
        <Pane :size="100 - ui.panelEditor - ui.panelPreview">
          <PanelTerminal />
        </Pane>
      </Splitpanes>
    </Pane>
  </Splitpanes>
</template>
​

ui为设置的页面size, 在nuxt平台, 如果包含client.vue文件, 需要等待这些文件 JS 内容执行完成才会从初始状态到达我们的预设。 通过使用计算属性并将它们绑定到 style 属性,修改后的代码可确保服务器呈现的 HTML 反映基于 ui 状态的预期初始布局。这消除了 SSR 期间潜在的布局闪烁或不一致。

Nuxt平台, 要充分利用SSR渲染的优势, 就要先给布局设置固定的style。

xml 复制代码
<script setup lang="ts">
// @ts-expect-error missing type
import { Pane, Splitpanes } from 'splitpanes'
​
const ui = useUiState()
const play = usePlaygroundStore()
​
const isMounted = useMounted()
const panelInitDocs = computed(() => isMounted.value || {
  width: `${ui.panelDocs}%`,
})
const panelInitRight = computed(() => isMounted.value || {
  width: `${100 - ui.panelDocs}%`,
})
const panelInitEditor = computed(() => isMounted.value || {
  height: `${ui.panelEditor}%`,
})
const panelInitPreview = computed(() => isMounted.value || {
  height: `${ui.panelPreview}%`,
})
const panelInitTerminal = computed(() => isMounted.value || {
  height: `${100 - ui.panelEditor - ui.panelPreview}%`,
})
</script>
​
<template>
    <splitpanes>
        <pane :size="ui.panelDocs" min-size="10" :style="panelInitDocs">
            <PanelGuide />
        </pane>
        <PanelSplitter />
        <pane :style="panelInitRight">
            <splitpanes horizontal>
                <Pane min-size="10" :size="ui.panelEditor" :style="panelInitEditor">
                    <PanelEditor :files="play.files" />
                </Pane>
                <PanelSplitter />
                <Pane min-size="10" :size="ui.panelPreview" :style="panelInitPreview">
                    <PanelPreview />
                </Pane>
                <PanelSplitter />
                <Pane min-size="10" :size="100 - ui.panelEditor - ui.panelPreview" :style="panelInitTerminal">
                    <PanelTerminal />
                </Pane>
            </splitpanes>
        </pane>
    </splitpanes>
</template>
    
​
​

PanelSplitter.vue

该文件防止布局拖动的布局消失

xml 复制代码
<script setup lang='ts'>
</script>
<template>
    <div class="splitpanes__splitter">
    </div>
</template>

这样随着 dom 被 mount之后, 就会立即更新需要的布局。

相关推荐
Liu.7742 分钟前
vue3 路由缓存导致onMounted无效
前端·javascript·vue.js
6***3491 小时前
Vue混合现实案例
前端·vue.js·mr
p***43481 小时前
Vue混合现实开发
前端·vue.js·mr
__花花世界1 小时前
前端日常工作开发技巧汇总
前端·javascript·vue.js
JIngJaneIL2 小时前
智慧物业|物业管理|基于SprinBoot+vue的智慧物业管理系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·论文·智慧物业管理系统
爬坑的小白2 小时前
vue 2.0 路由跳转时新开tab
前端·javascript·vue.js
爬坑的小白2 小时前
vue x 状态管理
前端·javascript·vue.js
泉城老铁4 小时前
Vue2实现语音报警
前端·vue.js·架构
q***04054 小时前
Vue项目中 安装及使用Sass(scss)
vue.js·sass·scss
临江仙4554 小时前
前端骚操作:用户还在摸鱼,新版本已悄悄上线!一招实现无感知版本更新通知
前端·vue.js