Svelte:使组件对变量有反应(重新渲染)
Svelte: make component reactive to variable (rerender)
我想在“view.current”发生变化时重新渲染“Body”(我的 svelte 组件),以便它渲染相应的 .svelte view/component:
App.svelte
<script>
import Header from "./components/Header.svelte";
import Footer from "./components/Footer.svelte";
import Body from "./components/Body.svelte";
import Login from "./views/Login.svelte";
import Dashboard from "./views/Dashboard.svelte";
import { view } from "./store";
</script>
<Header />
<Body>
{#if view.current === view.login}
<Login />
{:else if view.current === view.dashboard}
<Dashboard />
{/if}
</Body>
<Footer />
在“Body.svelte”中,我只有一个可以设置样式的插槽
Body.svelte
<div class="container">
<div class="content">
<slot></slot>
</div>
</div>
<style>
.container {
padding: 1em;
display: flex;
}
.content {
margin: auto;
}
</style>
在 Login.svelte(和其他 svelte 组件)中,我想更改“view.current”:
Login.svelte
<script>
import { view } from "../store";
function handleLoginClick() {
view.current = view.dashboard;
}
</script>
<button type="button" on:click={handleLoginClick} class="btn btn-primary btn-lg login-btn">Login</button>
<style>
.login-btn {
display: block;
margin: auto;
}
</style>
store.js
const user = {
username: "",
fullname: "",
role: null,
isLoggedIn: false
};
const view = {
login: 1,
dashboard: 2,
current: 1
};
export {
user,
view
}
“view.current”的值按预期更改,但“正文”没有 update/rerender。所以它总是显示 login.svelte 无论设置了什么“view.current”。
有没有一种快速简便的方法可以使“Body”对“view.current”做出反应,以便它重新呈现,以便重新评估“App.svelte”中的 if/else-block?
在组件中导入常规变量会创建该变量的本地副本。您在登录中指的 view
未与 App 中的共享,因此更改不会反映在那里。
像这样跨组件共享状态的“Svelte-way”是使用store。
在您的设置中,这意味着您首先将视图定义为商店:
import { writable } from 'svelte/store'
const view = writable({
login: 1,
dashboard: 2,
current: 1
});
在组件本身中,您必须在商店前面加上 $
<script>
function handleLoginClick() {
$view.current = $view.dashboard;
}
</script>
{#if $view.current === $view.login}
<Login />
{:else if $view.current === $view.dashboard}
<Dashboard />
{/if}
我想在“view.current”发生变化时重新渲染“Body”(我的 svelte 组件),以便它渲染相应的 .svelte view/component:
App.svelte
<script>
import Header from "./components/Header.svelte";
import Footer from "./components/Footer.svelte";
import Body from "./components/Body.svelte";
import Login from "./views/Login.svelte";
import Dashboard from "./views/Dashboard.svelte";
import { view } from "./store";
</script>
<Header />
<Body>
{#if view.current === view.login}
<Login />
{:else if view.current === view.dashboard}
<Dashboard />
{/if}
</Body>
<Footer />
在“Body.svelte”中,我只有一个可以设置样式的插槽
Body.svelte
<div class="container">
<div class="content">
<slot></slot>
</div>
</div>
<style>
.container {
padding: 1em;
display: flex;
}
.content {
margin: auto;
}
</style>
在 Login.svelte(和其他 svelte 组件)中,我想更改“view.current”:
Login.svelte
<script>
import { view } from "../store";
function handleLoginClick() {
view.current = view.dashboard;
}
</script>
<button type="button" on:click={handleLoginClick} class="btn btn-primary btn-lg login-btn">Login</button>
<style>
.login-btn {
display: block;
margin: auto;
}
</style>
store.js
const user = {
username: "",
fullname: "",
role: null,
isLoggedIn: false
};
const view = {
login: 1,
dashboard: 2,
current: 1
};
export {
user,
view
}
“view.current”的值按预期更改,但“正文”没有 update/rerender。所以它总是显示 login.svelte 无论设置了什么“view.current”。 有没有一种快速简便的方法可以使“Body”对“view.current”做出反应,以便它重新呈现,以便重新评估“App.svelte”中的 if/else-block?
在组件中导入常规变量会创建该变量的本地副本。您在登录中指的 view
未与 App 中的共享,因此更改不会反映在那里。
像这样跨组件共享状态的“Svelte-way”是使用store。
在您的设置中,这意味着您首先将视图定义为商店:
import { writable } from 'svelte/store'
const view = writable({
login: 1,
dashboard: 2,
current: 1
});
在组件本身中,您必须在商店前面加上 $
<script>
function handleLoginClick() {
$view.current = $view.dashboard;
}
</script>
{#if $view.current === $view.login}
<Login />
{:else if $view.current === $view.dashboard}
<Dashboard />
{/if}