Passing props down in Svelte

我的梦境 提交于 2019-12-11 00:16:48

问题


I'm trying to implement a fairly standard blog app using Svelte, Svelte Routing and Firestore, but I think I'm misunderstanding a fundamental part of how props are passed between components.

I based my initial code on the excellent tutorial on Fireship.io - which worked as per the tutorial: https://fireship.io/lessons/svelte-v3-overview-firebase/

From there I've added Svelte Routing - https://github.com/EmilTholin/svelte-routing - and I'm attempting to add a view route.

Relevant part of App.svelte:

<Router url="{url}">
    <Navbar user="{user}" />

    <div>
        <Route path="posts/:id" component="{Post}" />
        <Route path="posts/add" component="{PostForm}" />
        <Route path="posts" component="{Blog}" />
        <Route path="/" component="{Home}" />
    </div>

</Router>

In my Blog Component I use a component called PostTeaser, in which I pass a link to the post view page.

Blog Component:

<div class="posts">
    {#each posts as post}
      <PostTeaser post="{post}" />
    {/each}
</div>

PostTeaser component:

<div class="post-teaser">
   <h2 class="title is-3"><Link to="posts/{ post.id }" {post}>{ post.title }</Link></h2>
   <div class="post-teaser-content">{ post.content }</div>
</div>

Here I get a warning in the browser: <Link> was created with unknown prop 'post'

Although the teaser does appear on the screen with the correct information.

When I click through to the post, i.e. the Post Component, my data is undefined.

I am placing export let post; in the script tag of each of my components.

Should I be using a "store" for my data? At the moment I'm fetching my data in the BlogComponent and passing it down the line. It would seem that this is incorrect. Any help gratefully appreciated.

See here for fuller example: https://codesandbox.io/s/romantic-cannon-ri8lo


回答1:


With svelte-routing, you don't pass props from the <Link> component, you pass them from the <Route> component implicitly. Where you have this...

<Route path="posts/:id" component="{Post}" />

...you're telling the router that if the URL matches the pattern /posts/:id, it should render the Post component, passing it an id prop that matches that part of the URL.

The Post component is responsible for fetching its data based on that. So in this case, you could move the posts array into a separate module, and change Post.svelte accordingly:

<script>
  import posts from "./posts.js";

  export let id;
  $: post = posts.find(p => p.id == id);
</script>

<div class="post">
  <h1>{ post.title }</h1>
  <div class="post-content">{ post.content }</div>
</div>

(Note that props are stringified because they're derived from the href, so we need a == comparison rather than ===.)

Here's a working fork.




回答2:


Simple example:

Parent Component

<script>
  import PostTeaser from "./PostTeaser.svelte";
  let post = {
    first: 'First prop',
    second: 'Second prop'
  };
</script>

<PostTeaser {...post} />

Child Component

<script>
    export let first;
    export let second;
</script>

First prop: {first} <br>
Second prop: {second}

Code here: https://codesandbox.io/s/spread-props-using-svelte-y7xou



来源:https://stackoverflow.com/questions/56722539/passing-props-down-in-svelte

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!