sparky-spa / sparky
Requires
- php: >=7.2
- opis/closure: ^3.6
- webxid/basic-classes: ^1.2
Requires (Dev)
- webxid/debug-helpers: ^1.0
This package is auto-updated.
Last update: 2024-09-20 13:17:16 UTC
README
用于在PHP上开发单页应用程序的工具
易于开始,易于使用
如何使用
安装
运行 composer require sparky-spa/sparky
设置配置
设置设置
\SparkySpa\Sparky::config([ // Mandatory properties 'namespace' => 'App\SparkyComponent', // the namespace of your components 'ajax_uri' => '<ajax_uri>', // endpoint for ajax request. It could be relate or absolute link. 'view_callback' => function(string $view_name, array $data = []): string { // here you can use any views handler, blade, twig, handlebar etc. // Or, just implement the native PHP includes things return view($view_name, $data) ->render(); }, // Optional properties 'return_jquery_element' => true, // TRUE by default. If TRUE, an event listener will receive `$(this)` otherwise `this` 'is_dev_mode' => true, // FALSE by default. If TRUE, will display threw errors instead return 500 Internal Server Error ]);
实现 ajax_uri
端点
它必须支持以下URI
// POST <ajax_uri>/{$component_name}/{$action}/{$args} // POST <ajax_uri>/{$component_name}/{$action} // POST <ajax_uri>/{$component_name} // GET <ajax_uri>/{\SparkySpa\Sparky::NAME_MINI_JS}
此外,使用函数 handleHttpRequest()
正确实现端点
对于 POST <ajax_uri>/....
请求
use function SparkySpa\handleHttpRequest; echo handleHttpRequest( $component_name, $action, $args, $post_body );
对于 GET <ajax_uri>/{Sparky::NAME_MINI_JS}
请求
use function SparkySpa\handleHttpRequest; use SparkySpa\Sparky; echo handleHttpRequest( Sparky::NAME_MINI_JS );
请随意使用此工具 😉
后端
实现组件
让我们假设,我们有一个组件
namespace App\SparkyComponent; use SparkySpa\Component; class ChatCheckerComponent extends Component { #region Actions /** * @inheritDoc */ public function render() { return $this->view('spa/chat_checker'); } #endregion }
将组件插入页面
所有以下变体都将正常工作
use function SparkySpa\sparky; use App\SparkyComponent\ChatCheckerComponent; echo sparky('chat_checker', []); echo sparky(ChatCheckerComponent::getName(), []); echo ChatCheckerComponent::getTplBody([]);
如果您将组件放置到附加命名空间中(例如 User\ChatCheckerComponent
),请使用以下语法
use function SparkySpa\sparky; echo sparky('user.chat_checker');
组件动作
组件动作的调用顺序
$component->mount(); // it doesn't call in Ajax request $component->beforeExecuting(); $response = $component->customAction(); // an emitted method if (!is_string($response)) { $component->beforeRendering(); $response = $component->render(); } $component->afterRendering();
customAction
这是一个通过 emit
动作调用的动作。
返回一个字符串以跳过 $component->render();
调用。返回的字符串将作为ajax请求的响应。在这种情况下,将跳过 $component->beforeRendering();
动作。因此,如果需要,请将其放在 $component->customAction();
内部调用。
视图
发射组件动作
onClick: 发射动作
它向后端发送请求以执行动作
<div spa:click="action_name('param')"></div>
onClick: 初始化事件
它不会向后端发送请求,但仅触发事件/动作监听器
<div spa:click="event:event_name('param')"></div>
发射动作
<div spa:emit="action_name({name: 123})">0s delay by default</div> <div spa:emit.750ms="action_name('param')">trigger action in 750ms after loading</div> <div spa:emit.2s="action_name('param_1', 'param_2')"></div> <div spa:emit.5m="action_name()"></div> <div spa:emit.1h="action_name"></div>
时间 - 是Sparky加载后动作发射的延迟时间
初始化组件事件
页面/组件加载时的动作
spa:emit 和 spa:event 之间的主要区别是后者初始化事件监听器但不在后端调用组件动作
<div spa:event="event_name({name: 123})">0s interval by default</div> <div spa:event.750ms="event_name('param')">trigger event in 750ms after loading</div> <div spa:event.2s="event_name('param_1', 'param_2')"></div> <div spa:event.5m="event_name()"></div> <div spa:event.1h="event_name"></div>
将组件属性绑定到HTML字段
component_property_name
必须是组件的公共属性
<input spa:bind="component_property_name" type="text" name="field-name"> <input spa:bind type="text" name="component_property_name">
JavaScript
Sparky加载事件
使用加载事件很重要,因为这是一种安全的方法,可以防止错误 Uncaught ReferenceError: Sparky is not defined
document.addEventListener('SparkySpaLoad', function() { // a code });
事件列表
在页面加载时初始化一次
SparkySpaSetConfig
- 目前无法设置Sparky配置。如果您不确定,请勿使用此事件SparkySpaBeforeInit
- 配置设置后的事件SparkySpaInit
- 所有Sparky元素都已初始化
在页面加载后和每次组件从后端接收到动作请求的响应后初始化
SparkySpaLoad
- 在组件事件队列处理之前初始化
在JS中发射组件动作
以下执行将调用组件方法
document.addEventListener('SparkySpaLoad', function() { Sparky.emitTo('component_name', 'action_name'); let data = []; Sparky.emitTo('component_name', 'action_name', data); Sparky.emitTo('component_name', 'action_name', [], () => {}); // this emition will not replace a component html on the page Sparky.emitQuietlyTo('component_name', 'action_name', data, (component, response) => { // a code }); });
action_name
- 它是要调用的组件方法名。它也是监听器的 event_name
。 data
- 这是 action_name
方法的参数列表。 callback
- 它将在发射请求完成后执行,但在监听器调用之前。
初始化组件事件
在JS中初始化组件事件
它也不会调用组件方法,但会初始化事件监听器
document.addEventListener('SparkySpaLoad', function() { Sparky.initEventTo('component_name', 'event_name'); Sparky.initEventTo('component_name', 'event_name', []); Sparky.initEventTo('component_name', 'event_name', [], dom_element); Sparky.initEventAny('event_name'); // inits all events with `event_name` without any relation to a component. Sparky.initEventAny('event_name', []); // inits all events with `event_name` without any relation to a component. Sparky.initEventAny('event_name', [], dom_element); // inits all events with `event_name` without any relation to a component. });
JS中的事件/动作监听器
使用以下内容来监听事件
document.addEventListener('SparkySpaLoad', function() { Sparky.on('component_name', 'event_name', (dom_element, event_data, component) => {}); // listens all events with `event_name` without any relation to a component. Sparky.onAny('event_name', (dom_element, event_data, component) => { if (!component.is('component_name')) { return; } if (!dom_element) { // dom_element coould be null in 2 cases // 1. There was calling `Sparky.initEventTo()` without `dom_element` // 2. A component has been refreshed and the element was replaced with new one return Sparky.LISTENER_FORGET; // will remove the listener from a stack } // a code }); });
event_name
- 它是被调用的组件方法名。 component_name
- 事件的事件组件名称。
event_data.response
- 如果发出动作(非事件),则将包含响应的HTML主体
注意 不要检查组件
保留事件名称
sparky:update_binds
sparky:update_binds
- 当绑定的标签更新组件属性时执行。
<input spa:bind="component_property_name" type="text" name="field-name"> <input spa:bind type="text" name="component_property_name">
此事件将更新的属性列表传递给监听器
警告
请勿将安全数据传递到组件的公共属性中。它会传递到前端,并可能在浏览器中读取