问题
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