Svelte初始加载innerWidth为undefined致组件渲染异常求助
修复Svelte初始加载时设备尺寸判断错误的问题
问题现象
通过svelte:window绑定innerWidth更新deviceSize状态,但页面初始加载时innerWidth为undefined,导致isDesktop始终为false,强制渲染MobileComponent,即使桌面端打开也会出现该问题。
问题根源
- 初始渲染阶段,
svelte:window的innerWidth还未完成绑定,值为undefined,此时所有数值比较都会返回false,直接进入else分支设置移动端状态。 - 即便给
deviceSizestore设置默认值,组件内的响应式语句会在innerWidth绑定完成后覆盖默认值,导致初始判断失效。
修复方案
1. 给innerWidth设置初始值
在尺寸判断组件中,为innerWidth赋值初始窗口宽度,确保首次渲染就能正确计算设备尺寸:
<script lang="ts"> import { deviceSize } from "$lib/stores"; // 初始化为当前窗口宽度,服务端渲染时通过typeof window避免报错 let innerWidth = typeof window !== 'undefined' ? window.innerWidth : 0; $: if (innerWidth >= 1652) { $deviceSize = { xl: true, lg: false, md: false, dsm: false, sm: false }; } else if (innerWidth >= 1240 && innerWidth < 1652) { $deviceSize = { xl: false, lg: true, md: false, dsm: false, sm: false }; } else if (innerWidth >= 794 && innerWidth < 1240) { $deviceSize = { xl: false, lg: false, md: true, dsm: false, sm: false }; } else if (innerWidth >= 640 && innerWidth < 794) { $deviceSize = { xl: false, lg: false, md: false, dsm: true, sm: false }; } else { $deviceSize = { xl: false, lg: false, md: false, dsm: false, sm: true }; } </script> <svelte:window bind:innerWidth />
2. 优化deviceSize store默认值(可选)
如果需要适配服务端渲染场景,可在store中设置合理的初始状态,比如默认桌面端:
// $lib/stores.ts import { writable } from 'svelte/store'; export const deviceSize = writable({ xl: true, lg: false, md: false, dsm: false, sm: false });
3. 简化App.svelte的判断逻辑
合并条件判断,同时确保响应式依赖正确:
<script> import { deviceSize } from "$lib/stores"; import DesktopComponent from './DesktopComponent.svelte'; import MobileComponent from './MobileComponent.svelte'; $: isDesktop = $deviceSize.xl || $deviceSize.lg; </script> {#if isDesktop} <DesktopComponent /> {:else} <MobileComponent /> {/if}
关键说明
- 初始赋值
innerWidth时加入typeof window !== 'undefined'判断,避免服务端渲染时因window不存在引发报错。 - 响应式语句
$:会在innerWidth初始值设置后、窗口resize时自动触发,保证设备状态实时更新。
内容的提问来源于stack exchange,提问作者codeforfun
相关产品推荐
相关产品推荐

