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

相关推荐
打瞌睡的朱尤6 小时前
建立vue项目
vue.js
bearpping8 小时前
Spring Boot + Vue 全栈开发实战指南
vue.js·spring boot·后端
儒雅的烤地瓜11 小时前
Vue | 一文详解Vue3中的Setup()函数
vue.js·vue3·vue2·组合式api·setup函数·option api
网络安全学习库11 小时前
很喜欢Vue,但还是选择了React: AI时代的新考量
vue.js·人工智能·react.js·小程序·aigc·产品经理·ai编程
.生产的驴11 小时前
Vue3 超大字体font-slice按需分片加载,极速提升首屏速度, 中文分片加载方案,性能优化
前端·vue.js·windows·青少年编程·性能优化·vue·rescript
Hello--_--World12 小时前
VUE3:基础篇官网笔记
前端·vue.js·笔记
我是伪码农12 小时前
vue复习
前端·javascript·vue.js
cch891813 小时前
易语言VS VUE:编程工具终极对决
前端·javascript·vue.js
一 乐13 小时前
鲜花商城|基于springboot + vue鲜花商城系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·鲜花商城系统
IT东14 小时前
Vue 多环境部署全解析:解决测试与生产一致性难题
前端·javascript·vue.js