ДокументацияСовместные контракты
Действия и навигация
Взаимодействие в Nexy осуществляется через единую систему Действий и Навигации, гарантируя, что интерфейс и серверная часть остаются синхронизированными без ручного связующего кода API.
Контракт действия
Действие — это серверная функция, которая обрабатывает мутацию (например, обновление базы данных).
- Типизированный ввод: действия определены в Python с подсказками типов. Nexy генерирует соответствующий клиент TypeScript, поэтому вы получаете автозаполнение и проверку в своей IDE.
- Атомное выполнение: действие представляет собой одиночный
POSTзапрос. - Обработка результатов: действия возвращают типизированный результат, который клиент может использовать для обновления пользовательского интерфейса.
from pydantic import BaseModelfrom nexy.decorators import Action class Todo(BaseModel): title: str done: bool = False @Actionasync def add_todo(title: str) -> Todo: return Todo(title=title)Страница вызывает его с объявленным вводом Python и получает в ответ типизированный Todo:
import { useAction } from "@nexy/client";import { add_todo } from "@nexy/actions"; export default function Todos() { const { run, pending, data } = useAction(add_todo); return ( <button disabled={pending} onClick={() => run({ title: "Write the docs" })}> {data ? `Added ${data.title}` : "Add"} </button> );}Компонент представляет собой остров представления, а контроллер возвращает представление:
import { useAction } from "@nexy/client";import { add_todo } from "@nexy/actions"; export function Todos() { const { run, pending, data } = useAction(add_todo); return ( <button disabled={pending} onClick={() => run({ title: "Write the docs" })}> {data ? `Added ${data.title}` : "Add"} </button> );}from "@/components/Todos.tsx" import Todos<Todos directive="client:load" />Клиентская навигация
Навигация в Nexy «умная». Вместо полной перезагрузки браузера Nexy меняет содержимое текущей страницы, сохраняя при этом активные макеты.
- Компонент
Link: используйте компонентLinkдля конкретной платформы для выполнения переходов на стороне клиента. - Программная навигация: используйте
useRouter()из@nexy/clientи вызывайтеpush()для изменения страниц в ответ на логику (например, после успешного входа в систему).
import { Link } from "@nexy/client"; export function Nav() { return ( <nav> <Link href="/">Home</Link> <Link href="/about" activeClassName="active">About</Link> </nav> );}import { useRouter } from "@nexy/client"; export function Done() { const router = useRouter(); return <button onClick={() => router.push("/dashboard")}>Continue</button>;}Координация: Действие → Навигация
Самый распространенный шаблон — выполнить действие, а затем перевести пользователя на новую страницу.
Порядок повторной проверки:
- Клиент вызывает Action.
- Действие выполняется на сервере и вызывает
revalidate("/path"). - Сервер возвращает результат с заголовком
x-nexy-revalidateс указанием устаревших путей. - Клиент обновляет содержимое страницы, чтобы отразить новое состояние.
from nexy.decorators import Action, revalidate @Actionasync def sign_in(email: str, password: str) -> bool: ok = check_password(email, password) revalidate("/dashboard") return okimport { useAction, useRouter } from "@nexy/client";import { sign_in } from "@nexy/actions"; export default function Login() { const router = useRouter(); const { run } = useAction(sign_in, { onSuccess: (ok) => { if (ok) router.push("/dashboard"); }, }); return <button onClick={() => run({ email: "ada@example.com", password: "..." })}>Sign in</button>;}import { useAction } from "@nexy/client";import { sign_in } from "@nexy/actions"; export function Login() { const { run } = useAction(sign_in, { onSuccess: (ok) => { if (ok) window.location.assign("/dashboard/"); }, }); return <button onClick={() => run({ email: "ada@example.com", password: "..." })}>Sign in</button>;}check_password означает вашу собственную проверку. См. Действия для ошибок, форм без JavaScript и безопасности.
Реализация фреймворка
API для вызова действий и навигации зависит от платформы. См. руководство Различия для выбранной вами технологии: