dimtrovich/zygot

导出所有命名路由(BlitzPHP)并提供 JavaScript 中的 route() 函数。灵感来源于 tightenco/ziggy

安装: 46

依赖项: 0

建议者: 0

安全: 0

星标: 0

关注者: 1

分支: 0

开放问题: 0

语言:JavaScript

dev-main 2024-08-24 07:53 UTC

This package is auto-updated.

Last update: 2024-08-24 07:53:17 UTC


README

Zygot - Utilisez vos routes nommées BlitzPHP en JavaScript

Zygot – 在 JavaScript 中使用您的命名路由 BlitzPHP

GitHub Actions Status Latest Version on Packagist Downloads on Packagist Latest Version on NPM Downloads on NPM

鸣谢

Zygot 是为与 BlitzPHP 兼容而改编的 Ziggy 包。因此,所有荣誉都归功于 Daniel CoulbourneJake BathmanMatt StaufferJacob Baker-Kretzmar 以及 所有其他贡献者

Zygot 提供一个 JavaScript 辅助函数 route(),其功能与 BlitzPHP 相似,从而简化了在 JavaScript 中使用您的命名 BlitzPHP 路由。

Zygot 支持 BlitzPHP 的所有版本,从 0.4 开始,以及所有现代浏览器。

安装

使用 composer require dimtrovich/zygot 在您的 BlitzPHP 应用程序中安装 Zygot。

将函数 <?= zygot() ?> 添加到您的布局文件(在应用程序的 JavaScript 之前),现在辅助函数 route() 将在您的 JavaScript 代码中全局可用!

默认情况下,函数 <?= zygot() ?> 的输出包括应用程序中所有路由及其参数的列表。此路由列表包含在页面的 HTML 代码中,用户最终可以查看。要配置包含在此列表中的路由,或在不同页面上显示和隐藏不同的路由,请参阅 过滤路由

使用

辅助函数 route()

Zygot 的辅助函数 route() 的功能与 BlitzPHP 的辅助函数 route() 相似 - 您可以向它传递路由的名称和要传递给路由的参数,然后它会返回一个 URL。

基本使用

// app/Config/routes.php

$routes->get('posts', fn (Request $request) => /* ... */, ['as' => 'posts.index']);
// app.js

route('posts.index'); // 'https://zygot.test/posts'

带有参数

// app/Config/routes.php

$routes->get('posts/(:num)', fn (int $postId, Request $request) => /* ... */, ['as' => 'posts.show']);

// Uniquement BlitzPHP v0.4.2+
$routes->get('posts/{post}', fn ($post, Request $request) => /* ... */, ['as' => 'posts.show']);
// app.js

route('posts.show', 1);           // 'https://zygot.test/posts/1'
route('posts.show', [1]);         // 'https://zygot.test/posts/1'
route('posts.show', { post: 1 }); // 'https://zygot.test/posts/1'

带有多个参数

// app/Config/routes.php

$routes->get('events/(:num)/venues/(:num)', fn (int $eventId, int $venueId, Request $request) => /* ... */, ['as' => 'events.venues.show']);

// Uniquement BlitzPHP v0.4.2+
$routes->get('events/{event}/venues/{venue}', fn ($event, $venue, Request $request) => /* ... */, ['as' => 'events.venues.show']);
// app.js

route('events.venues.show', [1, 2]);                 // 'https://zygot.test/events/1/venues/2'
route('events.venues.show', { event: 1, venue: 2 }); // 'https://zygot.test/events/1/venues/2'

带有查询字符串参数

// app/Config/routes.php

$routes->get('events/(:num)/venues/(:num)', fn (int $eventId, int $venueId, Request $request) => /* ... */, ['as' => 'events.venues.show']);

// Uniquement BlitzPHP v0.4.2+
$routes->get('events/{event}/venues/{venue}', fn ($event, $venue, Request $request) => /* ... */, ['as' => 'events.venues.show']);
// app.js

route('events.venues.show', {
    event: 1,
    venue: 2,
    page: 5,
    count: 10,
});
// 'https://zygot.test/events/1/venues/2?page=5&count=10'

与 BlitzPHP 的辅助函数 route() 一样,Zygot 会自动将布尔查询参数编码为整数形式放入查询字符串中

route('events.venues.show', {
    event: 1,
    venue: 2,
	draft: false,
	overdue: true,
});
// 'https://zygot.test/events/1/venues/2?draft=0&overdue=1'

带有默认参数值

请参阅 BlitzPHP 关于路由默认参数值的文档

// app/Config/routes.php

$routes->get('{locale}/posts/(:num)', fn (int $postId, Request $request) => /* ... */, ['as' => 'posts.show']);
// app/Middlewares/SetLocale.php

config()->set('app.locale', $user->locale ?? 'de');
// app.js

route('posts.show', 1); // 'https://zygot.test/de/posts/1'

实践 AJAX 示例

const post = { id: 1, title: 'Zygot Stardust' };

return axios.get(route('posts.show', post)).then((response) => response.data);

Router

不带参数调用 Zygot 的 route() 辅助函数将返回一个 JavaScript Router 类的实例,该类具有一些其他有用的属性和方法。

检查当前路由:route().current()

// Route called 'events.index', with URI '/events'
// Current window URL is https://zygot.test/events

route().current();               // 'events.index'
route().current('events.index'); // true
route().current('events.*');     // true
route().current('events.show');  // false

可选地,current() 方法接受参数作为第二个参数,并将检查这些参数的值是否与当前 URL 中的值匹配

// Route called 'events.venues.show', with URI '/events/{event}/venues/{venue}'
// Current window URL is https://myapp.com/events/1/venues/2?authors=all

route().current('events.venues.show', { event: 1, venue: 2 }); // true
route().current('events.venues.show', { authors: 'all' });     // true
route().current('events.venues.show', { venue: 6 });           // false

检查是否存在路由:route().has()

// App has only one named route, 'home'

route().has('home');   // true
route().has('orders'); // false

获取当前路由参数:route().params

// Route called 'events.venues.show', with URI '/events/{event}/venues/{venue}'
// Current window URL is https://myapp.com/events/1/venues/2?authors=all

route().params; // { event: '1', venue: '2', authors: 'all' }

注意:使用 route().params 获取的参数值始终以字符串形式返回。

支持 TypeScript

目前,Zygot 不支持 TypeScript。欢迎所有贡献。

高级配置

JavaScript 框架

如果您不使用 <?= zygot() ?> 函数,Zygot 提供了一个 Klinge 命令来输出其配置和路由到文件:php klinge zygot:generate。默认情况下,此命令将您的路由存储在 resources/js/zygot.js 中,但您可以通过将不同值作为命令 Klinge 的参数或设置配置值 zygot.output.path 来自定义此路径。或者,您也可以从您的 API BlitzPHP 的端点以 JSON 格式返回 Zygot 的配置(请参阅下面的 从 API 端点获取 Zygot 的路由和配置 以获取配置示例)。

php klinge zygot:generate 生成的文件将如下所示:

// zygot.js

const Zygot = {
    routes: {"home":{"uri":"\/","methods":["GET","HEAD"],"domain":null},"login":{"uri":"login","methods":["GET","HEAD"],"domain":null}},
    url: 'http://zygot.test',
    port: false
};

export { Zygot };

您可以为 Zygot 的主要源文件创建别名,以简化导入。

// vite.config.js
export default defineConfig({
    resolve: {
        alias: {
            zygot: 'vendor/dimtrovich/zygot/dist',
            // 'vendor/dimtrovich/zygot/dist/vue.es.js' if using the Vue plugin
        },
    },
});
// webpack.mix.js

// Mix v6
const path = require('path');

mix.alias({
    zygot: path.resolve('vendor/dimtrovich/zygot/dist'),
    // 'vendor/dimtrovich/zygot/dist/vue' if using the Vue plugin
});

// Mix v5
const path = require('path');

mix.webpackConfig({
    resolve: {
        alias: {
            zygot: path.resolve('vendor/dimtrovich/zygot/dist'),
        },
    },
});

最后,像使用其他 JavaScript 库一样导入和使用 Zygot。由于 Zygot 的配置对象在此配置中不可全局访问,您通常需要手动将其传递给 route() 函数。

// app.js

import route from 'zygot';
import { Zygot } from './zygot';

// ...

route('home', undefined, undefined, Zygot);

Vue

Zygot 包含一个 Vue 插件,以简化在您的 Vue 应用程序中使用 route() 辅助函数。

import { createApp } from 'vue';
import { ZiggyVue } from 'zygot';
import { Zygot } from './zygot';
import App from './App';

createApp(App).use(ZiggyVue, Zygot);

// Vue 2
import Vue from 'vue'
import { ZiggyVue } from 'zygot';
import { Zygot } from './zygot';

Vue.use(ZiggyVue, Zygot);

如果您使用上面提到的导入别名 zygot,请确保在 vendor/dimtrovich/zygot/dist/vue.es.js(Vite)或 vendor/dimtrovich/zygot/dist/vue(Laravel Mix)中更新别名。

注意:如果您在您的视图中使用 <?= zygot() ?> 函数,Zygot 的配置将已全局可用,因此您不需要导入 Zygot 对象并将其传递到 use() 中。

现在您可以在 Vue 组件和模型中使用 route() 函数,如下所示:

<a class="nav-link" :href="route('home')">Accueil</a>

React

要使用 React 与 Zygot,首先导入 route() 函数和您的 Zygot 配置。由于 Zygot 的配置对象在此配置中不可全局访问,您需要手动将其传递给 route() 函数。

// app.js

import route from 'zygot';
import { Zygot } from './zygot';

// ...

route('home', undefined, undefined, Zygot);

我们正在努力为 Zygot 添加一个钩子以使其更加整洁,但截至目前,请确保按照上面所述将配置对象作为 route() 函数的第四个参数传递。

注意:如果您在您的视图中使用 <?= zygot() ?> 函数,包括在您的 React 应用程序中,route() 辅助函数将已全局可用,因此您不需要在所有地方导入 routeZygot

SPA 或单独的存储库

Zygot 的 route() 辅助函数也作为 NPM 包提供,用于在管理其后端 BlitzPHP 的 JavaScript 项目(即没有 Composer 或 vendor 目录)中使用。您可以使用 npm install zygot-js 安装 NPM 包。

要使此函数可用的前端路由可用,您可以执行 php klinge zygot:generate 并将生成的路由文件添加到您的项目中,或者您可以从您的 API BlitzPHP 的端点以 JSON 格式返回 Zygot 的配置(请参阅下面的 从 API 端点获取 Zygot 的路由和配置 以获取配置示例)。

然后,像上面那样导入和使用 Zygot。

// app.js

import route from 'zygot-js';

import { Zygot } from './zygot';
// ou...
const response = await fetch('/api/zygot');
const Zygot = await response.json();

// ...

route('home', undefined, undefined, Zygot);

路由过滤

Zygot 支持对其提供给 JavaScript 的路由进行过滤,这对于您不希望包含在客户端返回的响应源中的某些路由非常有用。路由过滤是可选的。默认情况下,Zygot 包含您应用程序中所有命名的路由。

基本过滤

要配置基本路由过滤,请在你的 BlitzPHP 应用程序中创建一个配置文件 app/Config/zygot.php,并设置 其中一个 参数 onlyexcept 为路由名称模式数组。

注意:您必须选择其一。同时设置 "only" 和 "except" 将完全禁用过滤并返回所有命名路由。

// app/Config/zygot.php

return [
    'only' => ['home', 'posts.index', 'posts.show'],
];

您还可以在路由过滤中使用星号作为通配符。在下面的示例中,admin.* 将排除命名路由 admin.loginadmin.register 

// app/Config/zygot.php

return [
    'except' => ['_debugbar.*', 'horizon.*', 'admin.*'],
];

使用组过滤

您还可以使用配置文件中的 "groups" 键定义您希望在不同应用程序位置的可用路由组。

// app/Config/zygot.php

return [
    'groups' => [
        'admin' => ['admin.*', 'users.*'],
        'author' => ['posts.*'],
    ],
];

然后,您可以通过传递组名到 zygot() 函数中暴露一个特定组。

// app/Views/layouts/main.php

<head>
	<title>---</title>
	...
	<?= zygot('admin') ?>
</head>

要暴露多个组,您可以传递一个组名数组。

// app/Views/layouts/main.php

<head>
	<title>---</title>
	...
	<?= zygot(['admin', 'author']) ?>
</head>

注意:向 zygot() 函数传递组名将始终优先于您的其他 onlyexcept 参数。

其他

使用 zygot 与内容安全策略

内容安全策略(CSP)可能会阻止在线脚本,包括由 zygot() 函数生成的脚本。如果您有 CSP 并使用 nonce 标记在线安全脚本,您可以将 nonce 作为 zygot() 函数的第二个参数传递,它将被添加到 Zygot 的脚本标签中。

zygot(nonce: 'your-nonce-here')
// ou
zygot(null, 'your-nonce-here')

禁用 route() 助手

如果您只想使用 zygot 函数将应用程序的路由暴露给 JavaScript,而不需要 route() 助手,请将配置值 skip-route-function 设置为 true

// app/Config/zygot.php

return [
    'skip-route-function' => true,
];

从 API 终端点获取 Zygot 路由和配置

Zygot 可以轻松地从 BlitzPHP 应用程序的 API 终端点返回其配置对象,格式为 JSON。例如,您可以配置一个类似以下的路由 /api/zygot 

// app/Config/routes.php

use Dimtrovich\Zygot\Zygot;

$routes->get('api/zygot', fn () => service('response')->json(new Zygot));

然后,在客户端,您可以通过 HTTP 请求获取配置。

// app.js

import route from 'zygot-js';

const response = await fetch('/api/zygot');
const Zygot = await response.toJson();

// ...

route('home', undefined, undefined, Zygot);

当您的应用程序路由发生变化时重新生成路由文件

如果您通过执行 php klinge zygot:generate 将 Zygot 路由导出为文件,您可能希望监控应用程序的路由文件,并在它们更新时自动重新执行命令。下面的示例是一个来自 Ziggy 的 Laravel Mix 插件,并且已被重新适配。感谢 Nuno Rodrigues 提供的 想法和实现示例 !

代码示例

const mix = require('laravel-mix');
const { exec } = require('child_process');

mix.extend('zygot', new class {
    register(config = {}) {
        this.watch = config.watch ?? ['app/Config/routes.php'];
        this.path = config.path ?? '';
        this.enabled = config.enabled ?? !mix.inProduction();
    }

    boot() {
        if (!this.enabled) return;

        const command = () => exec(
            `php klinge zygot: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', [])
    .zygot();

贡献

要开始为 Zygot 做贡献,请参阅 贡献指南

鸣谢

Zygot 是对 Ziggy 包的重新适配,以便能够在 BlitzPHP 中实现相同的功能。因此,所有的功劳都归功于 Daniel CoulbourneJake BathmanMatt StaufferJacob Baker-Kretzmar 以及 所有其他贡献者,我们衷心感谢他们为网络开发进步所做的努力。

感谢 Dimitri Sitchet Tomkeu 进行重新适配。

许可证

Zygot 是一个开源软件,在 MIT 许可证下发布。更多信息请参阅 LICENSE