简体   繁体   English

如何在 Svelte 上移动道具阵列?

[英]How do I shift a prop array on Svelte?

I'm trying to build a post list, and posts are passed down to my component as a prop array.我正在尝试构建一个帖子列表,帖子作为道具数组传递给我的组件。 The thing is: I need it to have second and later posts, as the first is shown by another component.问题是:我需要它有第二个和以后的帖子,因为第一个由另一个组件显示。

I'm trying to run an array.splice() but as I don't know much about how reactivity is build on Svelte, all ways I've tried or had broke everything or had no effect.我正在尝试运行一个 array.splice(),但由于我不太了解 Svelte 上的反应性是如何构建的,所以我尝试过或破坏了所有方法或没有效果。

Here's the component, where posts is the array I'm talking about:这是组件,其中 posts 是我正在谈论的数组:

<script>
import AppBlogPost from "./PostCards/AppBlogPost.svelte";

export let posts;
</script>

<style lang="scss">
</style>

<ul>
  {#each posts as post}
    <AppBlogPost {post} />
  {/each}
</ul>

To skip the first element in an array you can simply use array destructuring:要跳过数组中的第一个元素,您可以简单地使用数组解构:

let [, ...arr2] = arr

This will take your arr and write the first element nowhere (the empty space) while writing all the rest to arr2 using the spread operator.这将占用您的arr并将第一个元素写入任何地方(空白区域),同时使用扩展运算符将所有其余元素写入arr2

In the case of Svelte you probably want your post array still be reactive, so you have the mark assignment as such using $在 Svelte 的情况下,您可能希望您的 post 数组仍然是反应式的,因此您可以使用$标记分配

<script>
import AppBlogPost from "./PostCards/AppBlogPost.svelte";

export let posts;
$: [, ...otherPosts] = posts
</script>

<ul>
  {#each otherPosts as post}
    <AppBlogPost {post} />
  {/each}
</ul>

This also opens up a new possibility, I guess you are using posts[0] to display the first post differently ?这也开辟了一种新的可能性,我猜您正在使用posts[0]以不同的方式显示第一篇文章? If you change the reactive statement to $: [firstPost, ...otherPosts] = posts you have it in a handy variable instead!如果您将反应式语句更改为$: [firstPost, ...otherPosts] = posts您将它放在一个方便的变量中!

If members of your posts array changes, it won't be seen by svelte.如果您的posts数组的成员发生更改,则不会被 svelte 看到。 You have to assign values as new to your posts array, then svelte will see the array has been changed.您必须将值作为新值分配给您的posts数组,然后 svelte 将看到该数组已更改。

const remove=()=>{
  posts.splice(0,1)
  posts=[...posts]
}

Svelte detects where re-renders are needed by checking for assignment using the = operator, not mutation. Svelte 通过使用=运算符而不是变异检查赋值来检测需要重新渲染的位置。 For example:例如:

// no change detected
const obj = { foo: 1 }
obj.bar = 2

// change detected
let obj = { foo: 1 }
obj = { ...obj, bar: 2 }

As for Array#splice , it:至于Array#splice ,它:

changes the contents of an array by removing or replacing existing elements and/or adding new elements in place .通过删除或替换现有元素和/或在适当位置添加新元素更改数组的内容。

That "in place" means it mutates the array and returns the deleted items. “就地”意味着它会改变数组并返回已删除的项目。

If you're familiar with the splice API and want to use that, you could build an immutable version on top of it:如果您熟悉 splice API 并想使用它,您可以在它之上构建一个不可变的版本:

const spliceImmutable = arr => (...args) => {
    const clone = [...arr]
    clone.splice(...args)

    return clone
}

let arr = [0, 1, 2, 3, 4]
arr = spliceImmutable(arr)(2, 1, null) // [0, 1, null, 3, 4]

Or use custom logic based on Array#slice instead (more readable in my opinion):或者使用基于Array#slice 的自定义逻辑(我认为更具可读性):

let arr = [0, 1, 2, 3, 4]
arr = [ ...arr.slice(0, 2), null, ...arr.slice(3) ] // [0, 1, null, 3, 4]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM