SvelteKit中<svelte:window>绑定innerHeight等属性不生效
SvelteKit svelte:window绑定失效不更新问题修复
核心原因
svelte:window的所有属性绑定完全依赖客户端JS运行,SSR阶段window对象不存在,以下几种常见写法都会直接导致绑定失效:
- 对应页面/布局配置了
export const csr = false,关闭了客户端渲染,所有事件监听、双向绑定逻辑都不会执行 - 把
<svelte:window>标签放在了{#if}、{#key}、{#each}等条件渲染/循环块内部,组件初始化阶段无法注册window上的监听事件 - 生产构建时Svelte编译器的树摇优化误判绑定变量未被使用,直接移除了绑定逻辑(部分低版本Svelte存在该bug)
修复方案
方案1:修正写法适配内置绑定
调整代码结构,先保证基础配置正确:
- 移除页面/布局中
export const csr = false配置,开启客户端渲染 - 将
<svelte:window>标签移到组件DOM结构的最顶层,不要被任何条件渲染逻辑包裹 - 在
onMount生命周期中手动补充一次初始值赋值,绕开初始化阶段的绑定延迟问题
修正后的代码如下:
<script> import { onMount } from 'svelte'; import { navHeight, headerHeight, contentHeight } from "$lib/stores/dimensions.js" let innerHeight = 0; $: $contentHeight = innerHeight - $navHeight - $headerHeight; onMount(() => { // 初始化时主动赋值,避免首次加载不更新 innerHeight = window.innerHeight; }) </script> <!-- 放在组件顶层,不被条件块包裹 --> <svelte:window bind:innerHeight /> <p>当前窗口高度:{innerHeight}</p>
方案2:手动绑定事件(生产环境推荐)
如果调整写法后仍然存在偶现不更新的问题,直接弃用内置绑定,手动注册resize事件,稳定性更高,不受Svelte版本、编译器优化影响:
<script> import { onMount, onDestroy } from 'svelte'; import { navHeight, headerHeight, contentHeight } from "$lib/stores/dimensions.js" let innerHeight = 0; $: $contentHeight = innerHeight - $navHeight - $headerHeight; const updateHeight = () => { innerHeight = window.innerHeight; } onMount(() => { updateHeight(); window.addEventListener('resize', updateHeight); }) onDestroy(() => { // 组件卸载时移除监听,避免内存泄漏 window.removeEventListener('resize', updateHeight); }) </script> <p>当前窗口高度:{innerHeight}</p>
计算内容区高度这类布局逻辑,更推荐用CSS方案实现:比如给内容区设置
height: calc(100vh - 页头高度 - 导航栏高度),完全不需要JS监听窗口变化,性能更好也不会出现绑定失效问题。
内容的提问来源于stack exchange,提问作者Moon Rat
相关产品推荐
相关产品推荐

