SvelteKit中如何基于传入Props正确设置变量?
在SvelteKit组件中基于Props正确初始化值的方法
问题场景
在SvelteKit页面向组件传入testPlate对象props后,尝试直接在脚本顶层初始化testVar = testPlate.plateLength时,会抛出TypeError: Cannot read properties of undefined (reading 'plateLength')错误。临时用onMount嵌套setTimeout的方式可以规避,但这不是合理的实现方式。
错误代码示例:
<script> // @ts-nocheck export let testPlate; import * as Threlte from '@threlte/core'; import * as Three from 'three'; import * as Utils from 'three/src/math/MathUtils'; import { onMount } from 'svelte'; let testVar = testPlate.plateLength; console.log(testVar); </script>
临时解决方案(不推荐):
<script> // @ts-nocheck export let testPlate; import * as Threlte from '@threlte/core'; import * as Three from 'three'; import * as Utils from 'three/src/math/MathUtils'; import { onMount } from 'svelte'; let testVar; console.log(testVar); onMount(() => { setTimeout(() => { testVar = testPlate.plateLength; }, 1000); }); </script>
错误原因
组件初始化阶段,testPlate可能还未被父组件传入(比如父组件的testPlate是异步获取的数据),此时testPlate为undefined,直接访问其属性自然会报错。setTimeout只是通过延迟执行规避了这个问题,但无法保证时机准确,也不支持响应式更新。
正确解决方案
1. 使用可选链操作符处理空值
如果只是需要简单赋值,且能接受testVar初始为undefined,可以用可选链操作符?.避免报错:
<script> // @ts-nocheck export let testPlate; import * as Threlte from '@threlte/core'; import * as Three from 'three'; import * as Utils from 'three/src/math/MathUtils'; import { onMount } from 'svelte'; // 可选链确保testPlate为undefined时不会报错 let testVar = testPlate?.plateLength; console.log(testVar); </script>
2. 响应式声明(推荐)
利用Svelte的响应式特性,用$:标记语句,这样每当testPlate更新时,testVar会自动同步:
<script> // @ts-nocheck export let testPlate; import * as Threlte from '@threlte/core'; import * as Three from 'three'; import * as Utils from 'three/src/math/MathUtils'; import { onMount } from 'svelte'; // 响应式更新,testPlate变化时自动更新testVar $: testVar = testPlate?.plateLength; console.log(testVar); // 初始可能为undefined,testPlate传入后会自动输出正确值 </script>
这种方式是Svelte处理props依赖的标准做法,既避免了初始化报错,又能自动响应props的变化。
3. 在onMount中处理(适合DOM/Three.js初始化场景)
如果testVar需要用于组件挂载后的操作(比如Three.js对象初始化),可以直接在onMount中访问,但要先判断testPlate是否存在:
<script> // @ts-nocheck export let testPlate; import * as Threlte from '@threlte/core'; import * as Three from 'three'; import * as Utils from 'three/src/math/MathUtils'; import { onMount } from 'svelte'; let testVar; onMount(() => { // 先判断testPlate是否已传入 if (testPlate) { testVar = testPlate.plateLength; // 这里可以执行依赖testVar的Three.js初始化逻辑 console.log(testVar); } }); </script>
如果testPlate是异步加载的,还可以结合响应式监听:
<script> // @ts-nocheck export let testPlate; import * as Threlte from '@threlte/core'; import * as Three from 'three'; import * as Utils from 'three/src/math/MathUtils'; import { onMount } from 'svelte'; let testVar; // 监听testPlate变化,一旦存在就更新testVar并执行逻辑 $: if (testPlate) { testVar = testPlate.plateLength; // 执行Three.js相关操作 } </script>
内容的提问来源于stack exchange,提问作者Avi4nFLu
相关产品推荐
相关产品推荐

