fetch rest api in svelte onmount 发生在屏幕渲染之后

fetch rest api in svelte onmount is happening after the screen is rendered

使用 svelte 文档中的 onMount 照片示例,我可以使用自己的休息 api(又一个待办事项 ..)来显示数据。我将其更改为将照片 html 放在单独的组件中并且它可以工作。这里是App.svelte

    <script>
        import { onMount } from 'svelte'
        import Photos from './Photos.svelte'
    
        let photos = []
    
        onMount(async () => {
            const res = await fetch('http:///mint20-loopback4:3000/todos');
            photos = await res.json();
            console.log('todolist : ', photos)
        })
    </script>
    
    <Photos bind:photos={photos}/>

然后我学习了 MDN svelte 教程并完成了它。后来,我从商店中删除了待办事项初始列表,并在 App.svelte 中添加了一个 onMount 提取。结果是一个空的待办事项列表,但是当我与应用程序交互时,显示了数据。

这是控制台输出

Todos.svelte with length of :  0 
into TodoStatus.svelte :  Array []
totalTodos :  undefined 
completedTodos :  undefined 
Todos length - mounted :  0 
todolist :  Array(7) [ {…}, {…}, {…}, {…}, {…}, {…}, {…} ]
completed mount :  Array(7) [ {…}, {…}, {…}, {…}, {…}, {…}, {…} ]```

和App.svelte

<script lang="ts">
    import Todos from './components/Todos.svelte'
    import Alert from './components/Alert.svelte'
    import { onMount } from 'svelte'
    import type { TodoType } from './types/todo.type'
    
    let initialTodos: TodoType[] = []
    
    onMount(async () => {
        const res = await fetch('http:///mint20-loopback4:3000/todos');
        const json = await res.json();
        console.log('todolist : ', json)
        json.forEach(element  => {
          let t: TodoType = { id: 0, title: '0', isComplete: true }
          t.id = element.id
          t.title = element.title
          if (element.isComplete === undefined) {
            t.isComplete = false
          }
          else {
            t.isComplete = element.isComplete
          }
          initialTodos.push(t)
        })
        console.log('completed mount : ', initialTodos)
   })
</script>
      
 <Alert />
 <Todos bind:todos={initialTodos} />

所以它在照片示例中如预期的那样运行,但在这个空数组被传递而不是在 onMount 之前传递的地方却没有。 todo 示例比只有单个组件的照片有更多的组件,但我只想说,我很困惑。我需要做什么才能让初始屏幕使用填充的数据?

只是补充一下——我在照片中包含了控制台登录,它也有相同的模式——第一个子组件日志,最后是 App.svelte 中的 onMount。然而在这里,数据显示正确。

所以我认为应该发生的是因为对数组的更改会动态反映在显示中,当数组更新时,显示也会更新。但在待办事项中,这并没有发生。

DOM 仅在变量 assignments 上更新。在您的示例中,您使用 .push() 方法将对象添加到数组。因此,您需要在 forEach 循环之后添加它以确保组件获得更新:

initialTodos = initialTodos;

另一种选择是内联执行此操作。您可以替换:

initialTodos.push(t)

initialTodos = [...initialTodos,t]

Here 是官方文档。