devcu / ziggy
在 JavaScript 中使用 Laravel 的命名路由。
This package is auto-updated.
Last update: 2024-09-14 23:54:13 UTC
README
Ziggy – 在 JavaScript 中使用 Laravel 路由
Ziggy 提供了一个 JavaScript route()
函数,其工作方式与 Laravel 中的相似,使得在 JavaScript 中使用命名的 Laravel 路由变得非常简单。
安装
使用 Composer 在 Laravel 应用中安装 Ziggy
composer require tightenco/ziggy
将 @routes
Blade 指令添加到您的主布局中(在您的应用程序 JavaScript 之前),然后 route()
辅助函数将全局可用!
默认情况下,
@routes
Blade 指令的输出包括所有应用程序路由及其参数的列表。此路由列表包含在页面 HTML 中,可以被最终用户查看。要配置哪些路由包含在此列表中,或在不同页面上显示和隐藏不同的路由,请参阅 过滤路由。
用法
route()
函数
Ziggy 的 route()
函数的工作方式与 Laravel 的 route()
辅助函数 相似——您可以传递路由的名称和您想要传递给路由的参数,然后它将生成一个 URL。
基本用法
Route::get('posts', fn (Request $request) => /* ... */)->name('posts.index');
route('posts.index'); // 'https://ziggy.test/posts'
参数
Route::get('posts/{post}', fn (Post $post) => /* ... */)->name('posts.show');
route('posts.show', 1); // 'https://ziggy.test/posts/1' route('posts.show', [1]); // 'https://ziggy.test/posts/1' route('posts.show', { post: 1 }); // 'https://ziggy.test/posts/1'
多个参数
Route::get('venues/{venue}/events/{event}', fn (Venue $venue, Event $event) => /* ... */) ->name('venues.events.show');
route('venues.events.show', [1, 2]); // 'https://ziggy.test/venues/1/events/2' route('venues.events.show', { venue: 1, event: 2 }); // 'https://ziggy.test/venues/1/events/2'
查询参数
Ziggy 将不匹配任何命名路由参数的参数添加为查询参数
Route::get('venues/{venue}/events/{event}', fn (Venue $venue, Event $event) => /* ... */) ->name('venues.events.show');
route('venues.events.show', { venue: 1, event: 2, page: 5, count: 10, }); // 'https://ziggy.test/venues/1/events/2?page=5&count=10'
如果您需要传递与路由参数同名查询参数,请将其嵌套在特殊的 _query
键下
route('venues.events.show', { venue: 1, event: 2, _query: { event: 3, page: 5, }, }); // 'https://ziggy.test/venues/1/events/2?event=3&page=5'
与 Laravel 一样,Ziggy 会自动将布尔查询参数编码为查询字符串中的整数
route('venues.events.show', { venue: 1, event: 2, _query: { draft: false, overdue: true, }, }); // 'https://ziggy.test/venues/1/events/2?draft=0&overdue=1'
默认参数值
Ziggy 支持默认路由参数值(Laravel 文档)。
Route::get('{locale}/posts/{post}', fn (Post $post) => /* ... */)->name('posts.show');
// app/Http/Middleware/SetLocale.php URL::defaults(['locale' => $request->user()->locale ?? 'de']);
route('posts.show', 1); // 'https://ziggy.test/de/posts/1'
示例
使用 axios
发送 HTTP 请求
const post = { id: 1, title: 'Ziggy Stardust' }; return axios.get(route('posts.show', post)).then((response) => response.data);
Router
类
使用无参数调用 Ziggy 的 route()
函数将返回其 JavaScript Router
类的一个实例,该类还具有其他一些有用的属性和方法。
检查当前路由:route().current()
// Laravel route called 'events.index' with URI '/events' // Current window URL is https://ziggy.test/events route().current(); // 'events.index' route().current('events.index'); // true route().current('events.*'); // true route().current('events.show'); // false
route().current()
可选地接受参数作为其第二个参数,并将检查这些参数的值是否与当前 URL 中的值匹配
// Laravel route called 'venues.events.show' with URI '/venues/{venue}/events/{event}' // Current window URL is https://myapp.com/venues/1/events/2?hosts=all route().current('venues.events.show', { venue: 1 }); // true route().current('venues.events.show', { venue: 1, event: 2 }); // true route().current('venues.events.show', { hosts: 'all' }); // true route().current('venues.events.show', { venue: 6 }); // false
检查是否存在路由:route().has()
// Laravel app has only one named route, 'home' route().has('home'); // true route().has('orders'); // false
检索当前路由参数:route().params
// Laravel route called 'venues.events.show' with URI '/venues/{venue}/events/{event}' // Current window URL is https://myapp.com/venues/1/events/2?hosts=all route().params; // { venue: '1', event: '2', hosts: 'all' }
注意:使用
route().params
获取的参数值始终以字符串形式返回。
路由模型绑定
Ziggy 支持 Laravel 的 路由模型绑定,甚至可以识别自定义路由键名。如果您将 JavaScript 对象作为路由参数传递给 route()
,Ziggy 将使用为该路由注册的路由模型绑定键来在对象内部找到正确的参数值。如果未明确为参数注册路由模型绑定键,Ziggy 将使用对象的 id
键。
// app/Models/Post.php class Post extends Model { public function getRouteKeyName() { return 'slug'; } }
Route::get('blog/{post}', function (Post $post) { return view('posts.show', ['post' => $post]); })->name('posts.show');
const post = { id: 3, title: 'Introducing Ziggy v1', slug: 'introducing-ziggy-v1', date: '2020-10-23T20:59:24.359278Z', }; // Ziggy knows that this route uses the 'slug' route-model binding key: route('posts.show', post); // 'https://ziggy.test/blog/introducing-ziggy-v1'
Ziggy 还支持在路由定义中直接声明的范围绑定的 自定义键。
Route::get('authors/{author}/photos/{photo:uuid}', fn (Author $author, Photo $photo) => /* ... */) ->name('authors.photos.show');
const photo = { uuid: '714b19e8-ac5e-4dab-99ba-34dc6fdd24a5', filename: 'sunset.jpg', } route('authors.photos.show', [{ id: 1, name: 'Ansel' }, photo]); // 'https://ziggy.test/authors/1/photos/714b19e8-ac5e-4dab-99ba-34dc6fdd24a5'
TypeScript
Ziggy 包含 TypeScript 类型定义,以及一个 Artisan 命令,可以生成额外的类型定义,以启用路由名称和参数的自动补全。
要生成路由类型,运行带有 --types
或 --types-only
选项的 ziggy:generate
命令
php artisan ziggy:generate --types
为了使您的 IDE 能够识别 Ziggy 的 route()
辅助函数是全局可用的,并正确地声明它,请将以下声明添加到项目中的某个 .d.ts
文件中
import { route as routeFn } from 'ziggy-js'; declare global { var route: typeof routeFn; }
如果您尚未安装 Ziggy 的 NPM 包,请在 jsconfig.json
或 tsconfig.json
中添加以下内容,以从您的供应商目录加载 Ziggy 的类型
{ "compilerOptions": { "paths": { "ziggy-js": ["./vendor/tightenco/ziggy"] } } }
JavaScript 框架
注意
许多应用程序不需要此处描述的额外设置——@routes
Blade 指令使 Ziggy 的 route()
函数和配置全局可用,包括在捆绑的 JavaScript 文件中。
如果您没有使用 @routes
Blade 指令,可以直接将 Ziggy 的 route()
函数和配置导入到 JavaScript/TypeScript 文件中。
生成和导入 Ziggy 的配置
Ziggy 提供了一个 Artisan 命令,可以将其配置和路由输出到文件
php artisan ziggy:generate
默认情况下,此命令将配置放在 resources/js/ziggy.js
中,但您可以通过传递 Artisan 命令的参数或设置 ziggy.output.path
配置值来自定义此路径。
ziggy:generate
创建的文件看起来像这样
// resources/js/ziggy.js const Ziggy = { url: 'https://ziggy.test', port: null, routes: { home: { uri: '/', methods: [ 'GET', 'HEAD'], domain: null, }, login: { uri: 'login', methods: ['GET', 'HEAD'], domain: null, }, }, }; export { Ziggy };
导入 route()
函数
您可以将 Ziggy 导入,就像导入任何其他 JavaScript 库一样。如果没有 @routes
Blade 指令,Ziggy 的配置不是全局可用的,因此必须手动将其传递给 route()
函数
import { route } from '../../vendor/tightenco/ziggy'; import { Ziggy } from './ziggy.js'; route('home', undefined, undefined, Ziggy);
为了简化导入 route()
函数,您可以在供应商路径上创建一个别名
// vite.config.js export default defineConfig({ resolve: { alias: { 'ziggy-js': path.resolve('vendor/tightenco/ziggy'), }, }, });
现在,您的导入可以缩短为
import { route } from 'ziggy-js';
Vue
Ziggy 提供了一个 Vue 插件,以便在您的 Vue 应用程序中轻松使用 route()
辅助函数
import { createApp } from 'vue'; import { ZiggyVue } from 'ziggy-js'; import App from './App.vue'; createApp(App).use(ZiggyVue);
现在您可以在 Vue 组件和模板中的任何地方使用 route()
函数
<a class="nav-link" :href="route('home')">Home</a>
如果您没有使用 @routes
Blade 指令,也要导入 Ziggy 的配置并将其传递给 .use()
import { createApp } from 'vue'; import { ZiggyVue } from 'ziggy-js'; import { Ziggy } from './ziggy.js'; import App from './App.vue'; createApp(App).use(ZiggyVue, Ziggy);
React
Ziggy 包括一个 useRoute()
钩子,以便在您的 React 应用程序中轻松使用 route()
辅助函数
import React from 'react'; import { useRoute } from 'ziggy-js'; export default function PostsLink() { const route = useRoute(); return <a href={route('posts.index')}>Posts</a>; }
如果您没有使用 @routes
Blade 指令,也要导入 Ziggy 的配置并将其传递给 useRoute()
import React from 'react'; import { useRoute } from 'ziggy-js'; import { Ziggy } from './ziggy.js'; export default function PostsLink() { const route = useRoute(Ziggy); return <a href={route('posts.index')}>Posts</a>; }
您还可以使 Ziggy
配置对象全局可用,这样您就可以在每次调用 useRoute()
时不必传递 Ziggy 的配置
// app.js import { Ziggy } from './ziggy.js'; globalThis.Ziggy = Ziggy;
单页应用 (SPA) 或独立仓库
Ziggy 的 route()
函数作为 NPM 包提供,可用于管理其 Laravel 后端之外的 JavaScript 项目(即没有 Composer 或 vendor
目录)。您可以使用 npm install ziggy-js
安装 NPM 包。
要使路由可用于前端,以便该函数可以使用,您可以选择运行 php artisan ziggy:generate
并将生成的配置文件添加到您的前端项目中,或者您可以从 Laravel API 的端点返回 Ziggy 的配置作为 JSON(请参阅下面的 从 API 端点检索 Ziggy 的配置 以获取如何设置此的示例)。
过滤路由
Ziggy 支持过滤其输出的路由列表,这在您有一些不希望包含和显示在 HTML 源中的路由时非常有用。
重要
从 Ziggy 的输出中隐藏路由不能替代彻底的身份验证和授权。应该保护不应公开访问的路由,无论它们是否被过滤出 Ziggy 的输出。
包含/排除路由
要设置路由过滤,在 Laravel 应用程序中创建一个位于 config/ziggy.php
的配置文件,并添加包含包含路由名称模式的数组之一的 either only
或 except
键。
注意:您必须选择其中一个。同时设置
only
和except
将完全禁用过滤并返回所有命名路由。
// config/ziggy.php return [ 'only' => ['home', 'posts.index', 'posts.show'], ];
您可以在路由过滤器中使用星号作为通配符。在下面的示例中,admin.*
将排除名为 admin.login
、admin.register
等
// config/ziggy.php return [ 'except' => ['_debugbar.*', 'horizon.*', 'admin.*'], ];
按组过滤
您还可以使用配置文件中的 groups
键来定义您希望在应用程序的不同位置提供的路由组。
// config/ziggy.php return [ 'groups' => [ 'admin' => ['admin.*', 'users.*'], 'author' => ['posts.*'], ], ];
然后,您可以通过将组名传递给 @routes
Blade 指令来公开特定的组。
{{-- authors.blade.php --}} @routes('author')
要公开多个组,您可以传递一个包含组名的数组。
{{-- admin.blade.php --}} @routes(['admin', 'author'])
注意:将组名传递给
@routes
指令将始终优先于您的其他only
或except
设置。
其他
TLS/SSL 终止和可信代理
如果您的应用程序正在使用 TLS/SSL 终止 或位于负载均衡器或代理后面,或者如果它托管在提供此类服务的平台上,Ziggy 可能会生成带有 http
方案的 URL,而不是您应用程序 URL 使用的 https
。为了解决这个问题,请根据 配置可信代理 的文档设置您的 Laravel 应用程序的可信代理。
使用 @routes
与内容安全策略
内容安全策略 (CSP) 可能会阻止内联脚本,包括 Ziggy 的 @routes
Blade 指令输出的脚本。如果您有一个 CSP 并使用 nonce 标记安全内联脚本,您可以将 nonce 传递给 @routes
指令,它将被添加到 Ziggy 的脚本标签中。
@routes(nonce: 'your-nonce-here')
禁用 route()
辅助函数
如果您只想使用 @routes
指令在 JavaScript 中提供 Ziggy 的配置,但不需要 route()
辅助函数,请将 ziggy.skip-route-function
配置设置为 true
。
从 API 端点检索 Ziggy 的配置
如果您需要通过网络从 Laravel 后端检索 Ziggy 的配置,您可以创建一个类似以下的路由:
// routes/api.php use Tighten\Ziggy\Ziggy; Route::get('api/ziggy', fn () => response()->json(new Ziggy));
当应用程序的路由更改时重新生成路由文件
如果您通过运行 php artisan ziggy:generate
将 Ziggy 配置作为文件生成,那么当应用程序的路由文件更改时,您可能需要重新运行该命令。下面的示例是一个 Laravel Mix 插件,但可以通过不使用 Mix 实现类似的功能。非常感谢 Nuno Rodrigues 提供了 想法和示例实现。有关 Vite 示例,请参阅 #655。
Laravel Mix 插件示例
const mix = require('laravel-mix'); const { exec } = require('child_process'); mix.extend('ziggy', new class { register(config = {}) { this.watch = config.watch ?? ['routes/**/*.php']; this.path = config.path ?? ''; this.enabled = config.enabled ?? !Mix.inProduction(); } boot() { if (!this.enabled) return; const command = () => exec( `php artisan ziggy:generate ${this.path}`, (error, stdout, stderr) => console.log(stdout) ); command(); if (Mix.isWatching() && this.watch) { ((require('chokidar')).watch(this.watch)) .on('change', (path) => { console.log(`${path} changed...`); command(); }); }; } }()); mix.js('resources/js/app.js', 'public/js') .postCss('resources/css/app.css', 'public/css', []) .ziggy();
贡献
要开始为 Ziggy 做贡献,请查看 贡献指南。
鸣谢
感谢 Caleb Porzio、Adam Wathan 和 Jeffrey Way 在巩固这个想法方面的帮助。
安全
请审查我们的 安全策略,了解如何报告安全漏洞。
许可
Ziggy 是在 MIT 许可下发布的开源软件。有关更多信息,请参阅 LICENSE。