介绍
简介将重点关注以下问题的一般答案如何在 Astro 中的组件之间共享状态?解决方案部分将重点关注如何在 Astro 中使用 cookie 同步客户端和服务器组件.
在客户端组件之间共享状态和事件
- 框架:Vue、Solid、Preact 等前端框架处理组件状态共享
- 库:对于无需承诺给定框架即可使用的解决方案,请参阅https://github.com/nanostores/nanostores https://github.com/nanostores/nanostores有关 Astro Docs 的更多详细信息https://docs.astro.build/en/core-concepts/sharing-state/ https://docs.astro.build/en/core-concepts/sharing-state/
- vanilla js(仅说明):与模块全局变量一样简单(正如用户 SP33D 提醒的那样)。注意导出变量是可能的,但导出函数是更理想的模式
const devices = {
poster:{}
}}
function get_devices(){
return devices
}
export{
get_devices
}
完整的项目示例https://github.com/MicroWebStacks/astro-home-control/blob/2107f94d0ba9ca76b43777d8ca24eae99b3e78cc/src/libs/power_state.js#L7 https://github.com/MicroWebStacks/astro-home-control/blob/2107f94d0ba9ca76b43777d8ca24eae99b3e78cc/src/libs/power_state.js#L7
使用 vanilla js 共享状态和事件
- Vanilla js :还可以在客户端组件之间使用自定义事件,其中 html 元素是事件的目标,如本例所示
...
event(panel,"update",data[name])
...
element.addEventListener("update",(event)=>{
panel_set_state(name,event.detail)
})
完整项目示例:https://github.com/MicroWebStacks/astro-home-control/blob/2107f94d0ba9ca76b43777d8ca24eae99b3e78cc/src/pages/index.astro#L54 https://github.com/MicroWebStacks/astro-home-control/blob/2107f94d0ba9ca76b43777d8ca24eae99b3e78cc/src/pages/index.astro#L54
客户端和服务器之间共享状态
服务器通过页面重新加载到客户端
服务器到客户端无需重新加载页面
对于动态服务器更改变量,可以使用服务器发送事件https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events
我不会在这里详细介绍它,因为这个问题不需要它,但它可以与 Astro 一起使用,并且可以在此处找到一个示例https://github.com/MicroWebStacks/astro-examples#03_sse-counter https://github.com/MicroWebStacks/astro-examples#03_sse-counter
在相同的范围内,也可以使用 websockets,但是对于这个问题来说,如果复杂性不是问题,那么也可以从客户端和服务器访问数据库。
服务器和客户端的持久性和同步
使用客户端存储
这是客户坚持其存储选择的一种可能的解决方案,缺点是
- 如果存储只有客户端知道,服务器应答会闪烁
- 或需要开发更多代码来处理客户端提交和服务器端端点捕获,这需要处理会话和用户管理!
对于那些对无闪烁状态高级示例感兴趣的人,请与 sessionStorage 和 url 参数共享这里的工作示例https://github.com/MicroWebStacks/astro-examples#14_client-storage-counter https://github.com/MicroWebStacks/astro-examples#14_client-storage-counter
使用cookie
这是最简单的方法,看解决方案
解决方案:如何使用cookie在Astro中同步客户端和服务器
问题帖子得到了正确的调查,然后陷入了如何使用 cookie 客户端:
这就是在客户端上设置和获取 cookie 所需的全部内容,只需几行普通的 JavaScript,没有依赖项。请参阅此问题/答案使用 JavaScript 设置 cookie 并获取 cookie https://stackoverflow.com/questions/14573223/set-cookie-and-get-cookie-with-javascript
这里针对计数器进行了缩小和定制,但对于过期处理,请参阅引用的问题
function get_counter(){
const entry = document.cookie.split(';').find(entry=>entry.replace(' ','').startsWith('counter='))
if(entry){
return parseInt(entry.split('=')[1])
}else{
return 0
}
}
function set_counter(counter){
document.cookie = `counter=${counter}`
console.log(`new counter value = ${counter}`)
}
客户端持久计数器示例
为了使示例更简单,我使用了计数器而不是语言
这是一个完整的例子
- github项目:https://github.com/MicroWebStacks/astro-examples#13_client-persistent-counter https://github.com/MicroWebStacks/astro-examples#13_client-persistent-counter
- 功能性的 Gitpod :https://gitpod.io/?on=gitpod#https://github.com/MicroWebStacks/astro-examples/tree/main/13_client-persistent-counter https://gitpod.io/?on=gitpod#https://github.com/MicroWebStacks/astro-examples/tree/main/13_client-persistent-counter
服务器端cookie的使用
在Astro中,计数器cookie可以如下使用
let counter = 0
const cookie = Astro.cookies.get("counter")
if(cookie?.value){
counter = cookie.value
}
console.log(`index.astro> cookie counter = ${counter}`)
潜在问题
- 确保 cookie 在部署主机中传递非常重要,因为这可能是阻止此解决方案的问题,可以在示例中使用服务器控制台日志进行检查