远程函数
约 827 字大约 3 分钟
2026-09-23
远程函数就是在服务器端定义的函数, 可以在客户端调用, 也就是客户端可以通过远程函数来调用服务器端的函数.
在当前版本中, 还需要打开实验性功能才能使用
// vite.config.ts
import adapter from '@sveltejs/adapter-auto'
import { sveltekit } from '@sveltejs/kit/vite'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
sveltekit({
compilerOptions: {
// Force runes mode for the project, except for libraries. Can be removed in svelte 6.
runes: ({ filename }) =>
filename.split(/[/\\]/).includes('node_modules') ? undefined : true,
// 1.添加 async 实验性功能
experimental: {
async: true
}
},
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
// See https://svelte.dev/docs/kit/adapters for more information about adapters.
adapter: adapter(),
typescript: {
config: (config) => {
config.include.push('../drizzle.config.ts')
}
},
// 2.添加远程函数实验性功能
experimental: {
remoteFunctions: true
}
})
]
})在打开实验功能后, 我们就可以在服务器端定义远程函数, 并在客户端调用了.
远程函数需要定义在 xxx.remote.ts 文件中, 不能直接定义在 xxx.ts 文件中, 因为远程函数是需要在服务器端执行的, 所以必须在服务器端定义.
query
query 适用于普通的获取数据操作
/src/routes/posts/page.remote.ts
import { query } from '$app/server'
import * as db from '$lib/server/database'
export const getPosts = query(async () => {
const posts = await db.query.post.findMany()
return posts
})/src/routes/posts/+page.svelte
<script lang="ts">
import { getPosts } from './page.remote.ts'
</script>
<ul>
{#each await getPosts() as { title, slug }}
<li><a href="/blog/{slug}">{title}</a></li>
{/each}
</ul>在每个字段中的 as 方法中, 可以传入一个默认值, 这样在表单中就会有一个默认值, 如果不传入默认值, 则默认值为空
/src/routes/login/page.remote.ts
import { form } from '$app/server'
import * as v from 'valibot'
export const newPost = form(
v.object({
title: v.string(),
content: v.string()
}),
async ({ title, content }) => {
// 这里就是处理表单提交的逻辑, 可以是数据库操作, 也可以是其他操作
console.log('title:', title)
console.log('content:', content)
return { success: true }
}
)/src/routes/login/+page.svelte
<script lang="ts">
import { newPost } from './page.remote.ts';
</script>
<form {...newPost}>
<input {...newPost.fields.title.as('text')} />
<!-- 显示错误信息 -->
{#each newPost.fields.title.issues() as issue}
<p class="issue">{issue.message}</p>
{/each}
<!-- 显示当前值 -->
<p>Current value: {newPost.fields.title.value()}</p>
<input {...newPost.fields.content.as('text',"init value")} />
<button type="submit">Submit</button>
</form>command
command 函数用于处理一些不需要返回数据的操作, 例如删除数据, 更新数据等
不过更推荐使用 form 因为 form 可以在没有 js 的情况下也能正常工作, 而 command 需要 js 才能正常工作
import { command, query } from '$app/server'
import * as db from '$lib/server/database'
import * as v from 'valibot'
export const addLike = command(v.string(), async (id) => {
await db.query.post.update({
where: (post, { eq }) => eq(post.id, id),
data: {
likes: post => post.likes + 1
}
})
})