SvelteKit中如何通过表单Action更新响应式变量smoothies
解决SvelteKit表单Action后更新响应式数据不刷新页面的问题
你当前的问题在于,使用use:enhance提交表单后,Action返回的smoothies没有更新页面的响应式数据。因为你直接解构了export let data,而这个data只有在页面加载或update函数触发时才会更新,你需要主动处理Action返回的结果并更新本地变量。
修改步骤:
声明独立的响应式变量存储smoothies
在+page.svelte的script里,不要直接解构data到smoothies,而是自己创建一个响应式变量,初始值从data获取:let smoothies = data.smoothies;这样你可以主动控制这个变量的更新,不受
data默认加载的影响。在handleSubmit中处理Action返回的结果
在handleSubmit的回调里,从result.data中拿到Action返回的排序后的数据,直接更新smoothies变量:const handleSubmit = ({ submitter }) => { // 提交前更新激活标签 activeTab = submitter.name; return async ({ result }) => { // 从Action返回结果中获取排序后的数据 smoothies = result.data.smoothies; }; };优化标签切换逻辑(可选)
用Svelte的条件绑定替代手动DOM操作,让代码更简洁易维护。
修改后的+page.svelte代码:
<script> import { enhance } from '$app/forms'; export let data; // 声明响应式变量,初始值来自load函数的数据 let smoothies = data.smoothies; // 记录当前激活的标签 let activeTab = 'created_at'; const handleSubmit = ({ submitter }) => { activeTab = submitter.name; return async ({ result }) => { smoothies = result.data.smoothies; }; }; </script> <div class="flex flex-col items-center mx-auto gap-8"> <a role="button" href="/create" class="btn btn-success mt-8">Create Smoothie</a> <form action="?/sortSmoothies" method="POST" use:enhance={handleSubmit}> <div class="tabs tabs-boxed"> <button type="submit" name="created_at" value="true" class="tab {activeTab === 'created_at' ? 'tab-active' : ''}" >Created</button> <button type="submit" name="title" value="true" class="tab {activeTab === 'title' ? 'tab-active' : ''}" >Title</button> <button type="submit" name="rating" value="true" class="tab {activeTab === 'rating' ? 'tab-active' : ''}" >Rating</button> </div> </form> <div class="grid 2xl:grid-cols-4 xl:grid-cols-3 lg:grid-cols-2 gap-6 mt-4"> {#each smoothies as smoothie} <div class="card w-96 bg-base-100 shadow-xl"> <div class="card-body"> <h2 class="card-title">{smoothie.title}</h2> <p>{smoothie.method}</p> <div class="rating absolute -right-5 -top-5"> <div class="mask mask-star-2 bg-orange-400 w-12 h-12 flex items-center justify-center font-bold" > {smoothie.rating} </div> </div> <div class="card-actions justify-end"> <a role="button" href="/{smoothie.id}" class="btn btn-warning btn-sm">Edit</a> <form action="?/deleteSmoothie" method="POST"> <input type="hidden" name="smoothie" value={JSON.stringify(smoothie)} /> <button type="submit" class="btn btn-error btn-sm">Remove</button> </form> </div> </div> </div> {/each} </div> </div>
为什么之前的写法无效?
- 你之前用
$: ({ smoothies } = data);,这是依赖data的响应式解构,但data只有在页面初始加载或调用update()函数时才会更新,而你在handleSubmit里没有触发update,也没有主动修改这个变量。 - 通过自己声明
let smoothies = data.smoothies,你可以直接从Action返回的结果中赋值更新,Svelte会自动响应这个变化并更新DOM,不需要刷新页面。
+page.server.js不需要修改
你的sortSmoothies Action已经正确返回了排序后的数据,保持原样即可。
内容的提问来源于stack exchange,提问作者bob
相关产品推荐
相关产品推荐

