typescript 如何通过onMount更新Svelte和Sveltekit中的HTML元素

8xiog9wr  于 2023-03-31  发布在  TypeScript
关注(0)|答案(1)|浏览(123)

我患有新冠病毒,想写一个有趣的小游戏。我正在用Svelte和Sveltekit写一个刽子手游戏。
我已经写了大部分的游戏,但我坚持揭示刽子手的divs。
下面是代码:https://timscodebase-didactic-palm-tree-7wx4w55459xfpxq5.github.dev/
src/lib/HangGrid.svelte中,我订阅了numberWrong,并试图在它发生变化时做出React。它正在工作,但我在尝试向节点列表中的元素添加类时出错。
下面是代码:

<script lang="ts">
    import { numberWrong } from '$lib/stores'
    import { onMount } from 'svelte'

    $: console.log('numberWrong from grid', $numberWrong)
    $: wrong = $numberWrong - 1

    let pieces_of_man: NodeListOf<Element>
    const setPiecesOfMan = (pieces: NodeListOf<Element>) => {
        pieces_of_man = pieces
        console.log(pieces_of_man)
    }

    onMount(async () => {
        setPiecesOfMan(document.querySelectorAll('.piece_of_man'))
    })

    $: current_piece = pieces_of_man[wrong]

    // This gives the error
    $: current_piece.classList.remove('white')

    // This gives "
    $: console.log('current_piece', current_piece)
</script>

下面是错误:

[HMR][Svelte] Unrecoverable HMR error in <HangGrid>: next update will trigger a full reload
logError @ proxy.js?v=02947d2a:15
Proxy<HangGrid> @ proxy.js?v=02947d2a:380
create_if_block_2 @ +page.svelte:61
create_if_block_1 @ +page.svelte:57
create_if_block @ +page.svelte:56
update @ +page.svelte:55
update @ index.mjs:1273
flush @ index.mjs:1233
Promise.then (async)
schedule_update @ index.mjs:1184
make_dirty @ index.mjs:2066
(anonymous) @ index.mjs:2104
handleSubmit @ +page.svelte:40
(anonymous) @ index.mjs:428
HangGrid.svelte:18 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading '-1')
    at $$self.$$.update (HangGrid.svelte:18:21)
    at init (index.mjs:2109:8)
    at new HangGrid (HangGrid.svelte:23:47)
    at createProxiedComponent (svelte-hooks.js?v=02947d2a:341:9)
    at new ProxyComponent (proxy.js?v=02947d2a:242:7)
    at new Proxy<HangGrid> (proxy.js?v=02947d2a:349:11)
    at Array.create_if_block_2 (+page.svelte:61:11)
    at Array.create_if_block_1 (+page.svelte:57:16)
    at Array.create_if_block (+page.svelte:56:16)
    at Object.update [as p] (+page.svelte:55:19)
rpppsulh

rpppsulh1#

$: current_piece = pieces_of_man[wrong]

// This gives the error
$: current_piece.classList.remove('white')

因为你使用的是SvelteKit,上面的代码在DOM被挂载之前首先在服务器上运行。因此,pieces_of_man的值是未定义的,这导致current_piece的值是-1,这就是为什么当你试图设置classList时会收到一个错误。
为了确保只在DOM挂载后运行它,请尝试将代码更新为:

<script lang="ts">
    import { numberWrong } from '$lib/stores'
    import { onMount } from 'svelte'

    $: console.log('numberWrong from grid', $numberWrong)
    $: wrong = $numberWrong - 1

    let pieces_of_man: NodeListOf<Element>
    let mounted = false // Tracks whether the DOM is mounted
    
    const setPiecesOfMan = (pieces: NodeListOf<Element>) => {
        pieces_of_man = pieces
        console.log(pieces_of_man)
    }

    onMount(async () => {
        setPiecesOfMan(document.querySelectorAll('.piece_of_man'))
        mounted = true // DOM is mounted
    })

    $: mounted && current_piece = pieces_of_man[wrong] // Runs only when DOM is mounted

    $: mounted && current_piece.classList.remove('white') // Runs only when DOM is mounted
 
    $: console.log('current_piece', current_piece)
</script>

Svelte也不推荐强制性地更新DOM。我建议你在Svelte中查看tutorial,以了解如何操作类。
谢谢!请多保重,早日康复。

相关问题