主题
JavaScript
在 Livewire 组件中使用 JavaScript
Livewire 和 Alpine 提供了大量实用工具,可以直接在 HTML 中构建动态组件,但是,有时候在组件中执行纯 JavaScript 会很有帮助。
类组件需要 @script 指令
本页面的示例使用裸 <script> 标签,这适用于单文件和多文件组件。如果您使用的是类组件(Blade 视图与 PHP 类在不同文件中),您必须用 @script 指令包裹您的 script 标签:
blade
@script
<script>
// 您的 JavaScript 代码...
</script>
@endscript这告诉 Livewire 为类组件正确处理执行时机。
执行脚本
您可以直接在组件模板内添加 <script> 标签,以便在组件加载时执行 JavaScript。
因为这些脚本由 Livewire 处理,它们在完美的时机执行——在页面加载后,但在 Livewire 组件渲染之前。这意味着您不再需要用 document.addEventListener('...') 包裹脚本来正确加载它们。
这也意味着延迟加载或条件加载的 Livewire 组件在页面初始化后仍然能够执行 JavaScript。
blade
<div>
...
</div>
<script>
// 每次将此组件加载到页面时,此 JavaScript 都会执行...
</script>这是一个更完整的示例,您可以在其中注册在 Livewire 组件中使用的 JavaScript 操作。
blade
<div>
<button wire:click="$js.increment">+</button>
</div>
<script>
this.$js.increment = () => {
console.log('increment')
}
</script>要了解更多关于 JavaScript 操作的信息,请访问操作文档。
从脚本中使用 $wire
当您在组件内添加 <script> 标签时,您会自动获得对 Livewire 组件的 $wire 对象的访问权限。
以下是使用简单的 setInterval 每 2 秒刷新组件的示例(您可以轻松地使用 wire:poll 来实现这一点,但这是演示要点的简单方式):
blade
<script>
setInterval(() => {
$wire.$refresh()
}, 2000)
</script>$wire 对象
$wire 对象是您与 Livewire 组件交互的 JavaScript 接口。它提供对组件属性、方法和与服务器交互的实用程序的访问。
在组件脚本内,您可以直接使用 $wire。以下是您将使用的最基本方法:
js
// 访问和修改属性
$wire.count
$wire.count = 5
$wire.$set('count', 5)
// 调用组件方法
$wire.save()
$wire.delete(postId)
// 刷新组件
$wire.$refresh()
// 分发事件
$wire.$dispatch('post-created', { postId: 2 })
// 监听事件
$wire.$on('post-created', (event) => {
console.log(event.postId)
})
// 访问根元素
$wire.$el.querySelector('.modal')完整的 $wire 参考
有关所有 $wire 方法和属性的完整列表,请参阅本页底部的 $wire 参考。
加载资源
组件 <script> 标签对于在每次 Livewire 组件加载时执行一些 JavaScript 很有用,但是,有时您可能希望随组件一起在页面上加载整个脚本和样式资源。
以下是使用 @assets 加载名为 Pikaday 的日期选择器库并在组件内初始化它的示例:
blade
<div>
<input type="text" data-picker>
</div>
@assets
<script src="https://cdn.jsdelivr.net/npm/pikaday/pikaday.js" defer></script>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/pikaday/css/pikaday.css">
@endassets
<script>
new Pikaday({ field: $wire.$el.querySelector('[data-picker]') });
</script>当此组件加载时,Livewire 将确保在评估脚本之前加载页面上的任何 @assets。此外,它将确保提供的 @assets 在每个页面上只加载一次,无论此组件有多少个实例,这与组件脚本不同,组件脚本会为页面上的每个组件实例进行评估。
拦截器
在三个级别拦截 Livewire 请求:action(最精细)、message(每个组件)和 request(HTTP 级别)。
js
// Action 拦截器 - 为每个 action 调用触发
$wire.intercept(callback) // 此组件上的所有 action
$wire.intercept('save', callback) // 仅 'save' action
Livewire.interceptAction(callback) // 全局(所有组件)
// Message 拦截器 - 为每个组件消息触发
$wire.interceptMessage(callback) // 来自此组件的消息
$wire.interceptMessage('save', callback) // 仅当消息包含 'save'
Livewire.interceptMessage(callback) // 全局(所有组件)
// Request 拦截器 - 为每个 HTTP 请求触发
$wire.interceptRequest(callback) // 涉及此组件的请求
$wire.interceptRequest('save', callback) // 仅当请求包含 'save'
Livewire.interceptRequest(callback) // 全局(所有请求)所有拦截器都返回一个取消订阅函数:
js
let unsubscribe = $wire.intercept(callback)
unsubscribe() // 移除拦截器Action 拦截器
Action 拦截器是最精细的。它们为组件上的每个方法调用触发。
js
$wire.intercept(({ action, onSend, onCancel, onSuccess, onError, onFailure, onFinish }) => {
// action.name - 方法名称 ('save', '$refresh' 等)
// action.params - 方法参数
// action.component - 组件实例
// action.cancel() - 取消此 action
onSend(({ call }) => {
// call: { method, params, metadata }
})
onCancel(() => {})
onSuccess((result) => {
// result: PHP 方法的返回值
})
onError(({ response, body, preventDefault }) => {
preventDefault() // 阻止错误模态框
})
onFailure(({ error }) => {
// error: 网络错误
})
onFinish(() => {
// 始终运行(成功、错误、失败或取消)
})
})Message 拦截器
Message 拦截器为每个组件更新触发。一个消息包含一个或多个 action。
js
$wire.interceptMessage(({ message, cancel, onSend, onCancel, onSuccess, onError, onFailure, onStream, onFinish }) => {
// message.component - 组件实例
// message.actions - 此消息中的 action 集合
// cancel() - 取消此消息
onSend(({ payload }) => {
// payload: { snapshot, updates, calls }
})
onCancel(() => {})
onSuccess(({ payload, onSync, onEffect, onMorph, onRender }) => {
// payload: { snapshot, effects }
onSync(() => {}) // 状态同步后
onEffect(() => {}) // 效果处理后
onMorph(async () => {}) // DOM morph 后(必须是 async)
onRender(() => {}) // 渲染完成后
})
onError(({ response, body, preventDefault }) => {
preventDefault() // 阻止错误模态框
})
onFailure(({ error }) => {})
onStream(({ json }) => {
// json: 解析的流式数据块
})
onFinish(() => {})
})Request 拦截器
Request 拦截器为每个 HTTP 请求触发。一个请求可能包含来自多个组件的消息。
js
$wire.interceptRequest(({ request, onSend, onCancel, onSuccess, onError, onFailure, onResponse, onParsed, onStream, onRedirect, onDump, onFinish }) => {
// request.messages - 此请求中的消息集合
// request.cancel() - 取消此请求
onSend(({ responsePromise }) => {})
onCancel(() => {})
onResponse(({ response }) => {
// response: Fetch Response(读取 body 之前)
})
onParsed(({ response, body }) => {
// body: 响应体作为字符串
})
onSuccess(({ response, body, json }) => {})
onError(({ response, body, preventDefault }) => {
preventDefault() // 阻止错误模态框
})
onFailure(({ error }) => {})
onStream(({ response }) => {})
onRedirect(({ url, preventDefault }) => {
preventDefault() // 阻止重定向
})
onDump(({ html, preventDefault }) => {
preventDefault() // 阻止 dump 模态框
})
onFinish(() => {})
})示例
组件的加载状态:
blade
<script>
$wire.intercept(({ onSend, onFinish }) => {
onSend(() => $wire.$el.classList.add('opacity-50'))
onFinish(() => $wire.$el.classList.remove('opacity-50'))
})
</script>删除前确认:
blade
<script>
$wire.intercept('delete', ({ action }) => {
if (!confirm('确定要删除吗?')) {
action.cancel()
}
})
</script>全局会话过期处理:
js
Livewire.interceptRequest(({ onError }) => {
onError(({ response, preventDefault }) => {
if (response.status === 419) {
preventDefault()
if (confirm('会话已过期。刷新页面?')) {
window.location.reload()
}
}
})
})Action 特定的成功通知:
blade
<script>
$wire.intercept('save', ({ onSuccess, onError }) => {
onSuccess(() => showToast('已保存!'))
onError(() => showToast('保存失败', 'error'))
})
</script>全局 Livewire 事件
Livewire 为您分发两个有用的浏览器事件,以便从外部脚本注册任何自定义扩展点:
html
<script>
document.addEventListener('livewire:init', () => {
// 在 Livewire 加载后但在页面初始化之前运行...
})
document.addEventListener('livewire:initialized', () => {
// 在 Livewire 完成页面初始化后立即运行...
})
</script>Livewire 全局对象
Livewire 的全局对象是从外部脚本与 Livewire 交互的最佳起点。
您可以从客户端代码的任何位置在 window 上访问全局 Livewire JavaScript 对象。
在 livewire:init 事件监听器内使用 window.Livewire 通常很有帮助。
访问组件
您可以使用以下方法访问当前页面上加载的特定 Livewire 组件:
js
// 获取页面上第一个组件的 $wire 对象...
let component = Livewire.first()
// 通过 ID 获取给定组件的 `$wire` 对象...
let component = Livewire.find(id)
// 通过名称获取组件 `$wire` 对象的数组...
let components = Livewire.getByName(name)
// 获取页面上每个组件的 $wire 对象...
let components = Livewire.all()与事件交互
除了从 PHP 中的单个组件分发和监听事件外,全局 Livewire 对象允许您从应用程序的任何位置与 Livewire 的事件系统 交互:
js
// 向任何正在监听的 Livewire 组件分发事件...
Livewire.dispatch('post-created', { postId: 2 })
// 通过名称向给定的 Livewire 组件分发事件...
Livewire.dispatchTo('dashboard', 'post-created', { postId: 2 })
// 监听从 Livewire 组件分发的事件...
Livewire.on('post-created', ({ postId }) => {
// ...
})在某些场景中,您可能需要注销全局 Livewire 事件。例如,当使用 Alpine 组件和 wire:navigate 时,由于在页面之间导航时会调用 init,可能会注册多个监听器。要解决这个问题,请使用 Alpine 自动调用的 destroy 函数。在此函数内循环遍历所有监听器以注销它们,防止任何不需要的累积。
js
Alpine.data('MyComponent', () => ({
listeners: [],
init() {
this.listeners.push(
Livewire.on('post-created', (options) => {
// 做一些事情...
})
);
},
destroy() {
this.listeners.forEach((listener) => {
listener();
});
}
}));使用生命周期钩子
Livewire 允许您使用 Livewire.hook() 挂钩到其全局生命周期的各个部分:
js
// 注册一个回调以在给定的内部 Livewire 钩子上执行...
Livewire.hook('component.init', ({ component, cleanup }) => {
// ...
})有关 Livewire 的 JavaScript 钩子的更多信息可以在下面找到。
注册自定义指令
Livewire 允许您使用 Livewire.directive() 注册自定义指令。
以下是自定义 wire:confirm 指令的示例,它使用 JavaScript 的 confirm() 对话框在发送到服务器之前确认或取消操作:
html
<button wire:confirm="确定吗?" wire:click="delete">删除文章</button>以下是使用 Livewire.directive() 实现 wire:confirm 的方法:
js
Livewire.directive('confirm', ({ el, directive, component, cleanup }) => {
let content = directive.expression
// "directive" 对象让您访问解析后的指令。
// 例如,对于 wire:click.prevent="deletePost(1)" 的值如下:
//
// directive.raw = wire:click.prevent
// directive.value = "click"
// directive.modifiers = ['prevent']
// directive.expression = "deletePost(1)"
let onClick = e => {
if (! confirm(content)) {
e.preventDefault()
e.stopImmediatePropagation()
}
}
el.addEventListener('click', onClick, { capture: true })
// 在 `cleanup()` 内注册任何清理代码,以防
// 在页面仍处于活动状态时从 DOM 中移除 Livewire 组件。
cleanup(() => {
el.removeEventListener('click', onClick)
})
})JavaScript 钩子
对于高级用户,Livewire 暴露了其内部客户端"钩子"系统。您可以使用以下钩子来扩展 Livewire 的功能或获取有关 Livewire 应用程序的更多信息。
组件初始化
每当 Livewire 发现新组件时——无论是在初始页面加载时还是之后——都会触发 component.init 事件。您可以挂钩到 component.init 以拦截或初始化与新组件相关的任何内容:
js
Livewire.hook('component.init', ({ component, cleanup }) => {
//
})有关更多信息,请参阅组件对象的文档。
DOM 元素初始化
除了在初始化新组件时触发事件外,Livewire 还为给定 Livewire 组件内的每个 DOM 元素触发事件。
这可用于在您的应用程序中提供自定义 Livewire HTML 属性:
js
Livewire.hook('element.init', ({ component, el }) => {
//
})DOM Morph 钩子
在 DOM morphing 阶段——发生在 Livewire 完成网络往返之后——Livewire 会为每个被修改的元素触发一系列事件。
js
Livewire.hook('morph.updating', ({ el, component, toEl, skip, childrenOnly }) => {
//
})
Livewire.hook('morph.updated', ({ el, component }) => {
//
})
Livewire.hook('morph.removing', ({ el, component, skip }) => {
//
})
Livewire.hook('morph.removed', ({ el, component }) => {
//
})
Livewire.hook('morph.adding', ({ el, component }) => {
//
})
Livewire.hook('morph.added', ({ el }) => {
//
})除了每个元素触发的事件外,每个 Livewire 组件还会触发 morph 和 morphed 事件:
js
Livewire.hook('morph', ({ el, component }) => {
// 在 `component` 中的子元素被 morph 之前运行(不包括部分 morphing)
})
Livewire.hook('morphed', ({ el, component }) => {
// 在 `component` 中的所有子元素被 morph 之后运行(不包括部分 morphing)
})服务端 JavaScript 求值
除了直接在组件中执行 JavaScript 外,您还可以使用 js() 方法从服务端 PHP 代码求值 JavaScript 表达式。
这通常用于在执行服务端操作后执行某种客户端后续操作。
例如,以下是一个 post.create 组件,在文章保存到数据库后触发客户端警告对话框:
php
<?php // resources/views/components/post/⚡create.blade.php
use Livewire\Component;
new class extends Component {
public $title = '';
public function save()
{
// 将文章保存到数据库...
$this->js("alert('文章已保存!')");
}
};JavaScript 表达式 alert('文章已保存!') 将在服务器上保存文章后在客户端执行。
您可以在表达式内访问当前组件的 $wire 对象:
php
$this->js('$wire.$refresh()');
$this->js('$wire.$dispatch("post-created", { id: ' . $post->id . ' })');常见模式
以下是在实际应用中使用 JavaScript 与 Livewire 的一些常见模式。
集成第三方库
许多 JavaScript 库需要在元素添加到页面时进行初始化。使用组件脚本在组件加载时初始化库:
blade
<div>
<div id="map" style="height: 400px;"></div>
</div>
@assets
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY"></script>
@endassets
<script>
new google.maps.Map($wire.$el.querySelector('#map'), {
center: { lat: {{ $latitude }}, lng: {{ $longitude }} },
zoom: 12
});
</script>与 localStorage 同步
您可以使用 $watch 将组件状态与 localStorage 同步:
blade
<script>
// 初始化时从 localStorage 加载
if (localStorage.getItem('draft')) {
$wire.content = localStorage.getItem('draft');
}
// 当值更改时保存到 localStorage
$wire.$watch('content', (value) => {
localStorage.setItem('draft', value);
});
</script>使用 @js 指令
如果您需要输出 PHP 数据以直接在 JavaScript 中使用,可以使用 @js 指令。
blade
<script>
let posts = @js($posts)
// "posts" 现在将是来自 PHP 的文章数据的 JavaScript 数组。
</script>最佳实践
组件脚本 vs 全局脚本
在以下情况下使用组件脚本:
- JavaScript 特定于该组件的功能
- 您需要访问
$wire或组件特定的数据 - 代码应在每次组件加载时运行
在以下情况下使用全局脚本:
- 注册自定义指令或钩子
- 设置全局事件监听器
- 初始化应用范围的 JavaScript
避免内存泄漏
在组件脚本中添加事件监听器时,Livewire 会在组件移除时自动清理它们。但是,如果您使用全局拦截器或钩子,请确保在适当时进行清理:
js
// 组件级别 - 自动清理 ✓
$wire.intercept(({ onSend }) => {
onSend(() => console.log('正在发送...'));
});
// 全局级别 - 在整个页面生命周期内存在
Livewire.interceptMessage(({ onSend }) => {
onSend(() => console.log('正在发送...'));
});调试技巧
从浏览器控制台访问组件:
js
// 获取页面上的第一个组件
let $wire = Livewire.first()
// 检查组件状态
console.log($wire.count)
// 调用方法
$wire.increment()监控所有请求:
js
Livewire.interceptRequest(({ onSend }) => {
onSend(() => {
console.log('请求已发送:', Date.now());
});
});查看组件快照:
js
let component = Livewire.first().__instance()
console.log(component.snapshot)性能考虑
- 在不应被 Livewire 的 DOM morphing 触及的元素上使用
wire:ignore - 使用
wire:model.debounce或 JavaScript 防抖来处理昂贵的操作 - 对于不立即可见的组件使用延迟加载(
lazy参数) - 考虑使用 islands 来隔离独立更新的区域
另请参阅
- 样式 — 为组件添加作用域 CSS
- Alpine — 使用 Alpine 实现客户端交互
- 操作 — 在组件中创建 JavaScript 操作
- 属性 — 使用 $wire 从 JavaScript 访问属性
- 事件 — 在 JavaScript 中分发和监听事件
参考
在扩展 Livewire 的 JavaScript 系统时,了解您可能遇到的不同对象非常重要。
以下是 Livewire 每个相关内部属性的详尽参考。
提醒一下,普通的 Livewire 用户可能永远不会与这些交互。这些对象大多数可用于 Livewire 的内部系统或高级用户。
$wire 对象
给定以下通用的 Counter 组件:
php
<?php
namespace App\Livewire;
use Livewire\Component;
class Counter extends Component
{
public $count = 1;
public function increment()
{
$this->count++;
}
public function render()
{
return view('livewire.counter');
}
}Livewire 以对象形式暴露服务端组件的 JavaScript 表示,通常称为 $wire:
js
let $wire = {
// 所有组件公共属性都可以直接在 $wire 上访问...
count: 0,
// 所有公共方法都在 $wire 上暴露和可调用...
increment() { ... },
// 如果存在,访问父组件的 `$wire` 对象...
$parent,
// 访问 Livewire 组件的根 DOM 元素...
$el,
// 访问当前 Livewire 组件的 ID...
$id,
// 通过名称获取属性的值...
// 用法: $wire.$get('count')
$get(name) { ... },
// 通过名称设置组件上的属性...
// 用法: $wire.$set('count', 5)
$set(name, value, live = true) { ... },
// 切换布尔属性的值...
$toggle(name, live = true) { ... },
// 调用方法...
// 用法: $wire.$call('increment')
$call(method, ...params) { ... },
// 定义 JavaScript 操作...
// 用法: $wire.$js('increment', () => { ... })
// 用法: $wire.$js.increment = () => { ... }
$js(name, callback) { ... },
// [已弃用] Entangle - 您可能不需要这个。
// 改用 $wire 直接访问属性。
// 用法: <div x-data="{ count: $wire.$entangle('count') }">
$entangle(name, live = false) { ... },
// 监视属性值的变化...
// 用法: Alpine.$watch('count', (value, old) => { ... })
$watch(name, callback) { ... },
// 通过向服务器发送消息来刷新组件
// 以重新渲染 HTML 并将其交换到页面中...
$refresh() { ... },
// 与上面的 `$refresh` 相同。只是一个更技术性的名称...
$commit() { ... }, // $refresh 的别名
// 监听从此组件或其子组件分发的事件...
// 用法: $wire.$on('post-created', () => { ... })
$on(event, callback) { ... },
// 监听从此组件或请求触发的生命周期钩子...
// 用法: $wire.$hook('message.sent', () => { ... })
$hook(name, callback) { ... },
// 从此组件分发事件...
// 用法: $wire.$dispatch('post-created', { postId: 2 })
$dispatch(event, params = {}) { ... },
// 向另一个组件分发事件...
// 用法: $wire.$dispatchTo('dashboard', 'post-created', { postId: 2 })
$dispatchTo(otherComponentName, event, params = {}) { ... },
// 仅向此组件分发事件,不向其他组件分发...
$dispatchSelf(event, params = {}) { ... },
// 直接向组件上传文件的 JS API
// 而不是通过 `wire:model`...
$upload(
name, // 属性名称
file, // File JavaScript 对象
finish = () => { ... }, // 上传完成时运行...
error = () => { ... }, // 上传过程中触发错误时运行...
progress = (event) => { // 上传进度时运行...
event.detail.progress // 1-100 的整数...
},
) { ... },
// 同时上传多个文件的 API...
$uploadMultiple(name, files, finish, error, progress) { },
// 在临时上传但未保存后移除上传...
$removeUpload(name, tmpFilename, finish, error) { ... },
// 为此组件实例注册 action 拦截器
// 用法: $wire.intercept(({ action, onSend, onCancel, onSuccess, onError, onFailure, onFinish }) => { ... })
// 或限定到特定 action: $wire.intercept('save', ({ action, onSuccess }) => { ... })
intercept(actionOrCallback, callback) { ... },
// intercept 的别名
interceptAction(actionOrCallback, callback) { ... },
// 为此组件实例注册 message 拦截器
// 用法: $wire.interceptMessage(({ message, cancel, onSend, onCancel, onSuccess, onError, onFailure, onFinish }) => { ... })
// 或限定到特定 action: $wire.interceptMessage('save', callback)
interceptMessage(actionOrCallback, callback) { ... },
// 为此组件实例注册 request 拦截器
// 用法: $wire.interceptRequest(({ request, onSend, onCancel, onSuccess, onError, onFailure, onFinish }) => { ... })
// 或限定到特定 action: $wire.interceptRequest('save', callback)
interceptRequest(actionOrCallback, callback) { ... },
// 获取底层的 "component" 对象...
__instance() { ... },
}您可以在 Livewire 关于在 JavaScript 中访问属性的文档 中了解更多关于 $wire 的信息。
snapshot 对象
在每个网络请求之间,Livewire 将 PHP 组件序列化为可以在 JavaScript 中使用的对象。此快照用于将组件反序列化回 PHP 对象,因此具有内置的防篡改机制:
js
let snapshot = {
// 组件的序列化状态(公共属性)...
data: { count: 0 },
// 关于组件的长期信息...
memo: {
// 组件的唯一 ID...
id: '0qCY3ri9pzSSMIXPGg8F',
// 组件的名称。例如 <livewire:[name] />
name: 'counter',
// 最初加载组件的网页的 URI、方法和区域设置。
// 这用于将原始请求的任何中间件
// 重新应用到后续组件更新请求(消息)...
path: '/',
method: 'GET',
locale: 'en',
// 任何嵌套的"子"组件列表。以内部模板 ID 为键,
// 组件 ID 为值...
children: [],
// 此组件是否"延迟加载"...
lazyLoaded: false,
// 上次请求期间抛出的任何验证错误列表...
errors: [],
},
// 此快照的安全加密哈希。这样,
// 如果恶意用户篡改快照以访问服务器上
// 不属于他们的资源,校验和验证将失败
// 并抛出错误...
checksum: '1bc274eea17a434e33d26bcaba4a247a4a7768bd286456a83ea6e9be2d18c1e7',
}component 对象
页面上的每个组件都有一个相应的 component 对象在幕后跟踪其状态并暴露其底层功能。这比 $wire 更深一层。它仅用于高级用法。
以下是上述 Counter 组件的实际 component 对象,JS 注释中描述了相关属性:
js
let component = {
// 组件的根 HTML 元素...
el: HTMLElement,
// 组件的唯一 ID...
id: '0qCY3ri9pzSSMIXPGg8F',
// 组件的"名称"(<livewire:[name] />)...
name: 'counter',
// 最新的"效果"对象。效果是服务器
// 往返的"副作用"。包括重定向、文件下载等...
effects: {},
// 组件最后已知的服务端状态...
canonical: { count: 0 },
// 组件的可变数据对象,表示其
// 实时客户端状态...
ephemeral: { count: 0 },
// `this.ephemeral` 的响应式版本。对此对象的更改
// 将被 AlpineJS 表达式捕获...
reactive: Proxy,
// 通常在 Alpine 表达式中用作 `$wire` 的 Proxy 对象。
// 这旨在为 Livewire 组件提供
// 友好的 JS 对象接口...
$wire: Proxy,
// 任何嵌套的"子"组件列表。以内部模板 ID 为键,
// 组件 ID 为值...
children: [],
// 此组件的最后已知"快照"表示。
// 快照从服务端组件获取,用于
// 在后端重新创建 PHP 对象...
snapshot: {...},
// 上述快照的未解析版本。这用于在下次往返时
// 发送回服务器,因为 JS 解析会干扰 PHP 编码,
// 这通常会导致校验和不匹配。
snapshotEncoded: '{"data":{"count":0},"memo":{"id":"0qCY3ri9pzSSMIXPGg8F","name":"counter","path":"\/","method":"GET","children":[],"lazyLoaded":true,"errors":[],"locale":"en"},"checksum":"1bc274eea17a434e33d26bcaba4a247a4a7768bd286456a83ea6e9be2d18c1e7"}',
}message 负载
当在浏览器中对 Livewire 组件执行操作时,会触发网络请求。该网络请求包含一个或多个组件以及服务器的各种指令。在内部,这些组件网络负载称为"消息"。
"消息"表示当组件需要更新时从前端发送到后端的数据。组件在前端渲染和操作,直到执行需要它将其状态和更新发送到后端的操作。
您将在浏览器 DevTools 的网络选项卡中或 Livewire 的 JavaScript 钩子 中看到此模式:
js
let message = {
// 快照对象...
snapshot: { ... },
// 要在服务器上更新的属性的键值对列表...
updates: {},
// 要在服务端调用的方法(带参数)数组...
calls: [
{ method: 'increment', params: [] },
],
}