解决 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之后, 就会立即更新需要的布局。

相关推荐
醉の虾16 分钟前
Vue3 使用v-for 渲染列表数据后更新
前端·javascript·vue.js
chusheng184039 分钟前
Java项目-基于SpringBoot+vue的租房网站设计与实现
java·vue.js·spring boot·租房·租房网站
游走于计算机中摆烂的1 小时前
启动前后端分离项目笔记
java·vue.js·笔记
幼儿园的小霸王1 小时前
通过socket设置版本更新提示
前端·vue.js·webpack·typescript·前端框架·anti-design-vue
码蜂窝编程官方2 小时前
【含开题报告+文档+PPT+源码】基于SpringBoot+Vue的虎鲸旅游攻略网的设计与实现
java·vue.js·spring boot·后端·spring·旅游
乐闻x3 小时前
Vue.js 性能优化指南:掌握 keep-alive 的使用技巧
前端·vue.js·性能优化
533_4 小时前
[vue] 深拷贝 lodash cloneDeep
前端·javascript·vue.js
ZBY520315 小时前
【Vue】 npm install amap-js-api-loader指南
javascript·vue.js·npm
计算机毕设指导65 小时前
基于 SpringBoot 的作业管理系统【附源码】
java·vue.js·spring boot·后端·mysql·spring·intellij-idea
木子02046 小时前
前端VUE项目启动方式
前端·javascript·vue.js