六维教程

Astro 客户端脚本

前面(Astro 组件基础)说过,.astro 文件里 --- 之间的代码运行在「构建阶段」,那时还没有浏览器、没有 DOM,所以像下面这样写是无效的:

---
// 这部分在构建时运行,拿不到按钮
document.querySelector('button').addEventListener('click', () => {});
---

要操作 DOM、响应点击,必须把代码放到「浏览器里执行」。

用 script 标签写客户端脚本

在模板里直接写 <script> 标签,Astro 会把它当作浏览器端脚本处理并打包。

---
---
<button id="btn">点我</button>
<p id="tip">还没点</p>

<script>
  const btn = document.getElementById('btn');
  const tip = document.getElementById('tip');
  btn.addEventListener('click', () => {
    tip.textContent = '你点了按钮';
  });
</script>

这里的 script 会被 Astro 默认做打包、压缩和去重,每个页面只会加载一次。

脚本作用域

Astro 的 <script> 默认是「模块作用域」,变量不会污染全局,多个组件各自独立,不会互相冲突。

如果你确实需要暴露到全局(比如给别的脚本调用),可以用 is:global 指令。

<script is:global>
  window.myFlag = true;
</script>

引入 npm 包

<script> 里可以直接 import 已安装的包,Astro 会一并打包。

<script>
  import confetti from 'canvas-confetti'; // canvas-confetti 是一个撒花特效 npm 包
  document.getElementById('btn').addEventListener('click', () => {
    confetti();
  });
</script>

TypeScript 支持

<script> 默认支持 TS,直接写类型即可。

<script>
  const count: number = 1;
  console.log(count);
</script>

与组件数据联动

组件脚本算好的数据,想带到客户端脚本里,可以用 JSON 注入。

---
const config = { theme: 'dark', max: 10 };
---
<script define:vars={config}>
  // define:vars 把上面的 config 对象序列化后作为变量注入,这里可直接用 theme、max
  console.log(theme, max);
</script>

define:vars 会把对象序列化成变量传给脚本,适合把构建期数据传给运行期。

上一篇
Astro 插槽 slot
下一篇
Astro 局部样式