Vector:在 Blade 中使用 Vue 的最简方式
Source: Dev.to
你是否有过这样的感觉:在构建 Laravel 应用时,只需要一点点响应式功能?一个计数器。一个开关。它对完整的 Vue 组件来说显得有点小题大做,却又比原生 JavaScript 麻烦太多?
我一直在使用 Alpine.js,它很好,但我想要 Vue 的 Composition API——ref()、computed(),以及我已经熟悉的语法。所以我创建了 Vector。
这到底是什么?
Vector 是一个 Laravel 包,允许你直接在 Blade 模板中编写 Vue 的 “ 语法:
@vector
const count = ref(0);
@endvector
Clicked @{{ count }} times
就这么简单。无需为组件设置构建步骤。无需单独的 .vue 文件。只要 Blade 加上一点 Vue。
为什么要这么做?
我已经厌倦了以下的思考过程:
- “这里需要响应式”
- “我该不该写一个 Vue 组件?”
- “但这只是一个计数器…”
- “好吧,还是用 Alpine 吧”
- “等等,Alpine 怎么写计算属性来着?”
使用 Vector,答案永远是:像在 Vue 中一样编写,因为它 就是 Vue。
工作原理
@vector 指令会做几件事:
- 捕获你的 “ 块
- 去除 Vue 的导入(它们已经全局提供)
- 提取你的变量声明
随后它会生成一段脚本,将 Vue 挂载到下一个兄弟元素上:
(function(__script) {
function __mount() {
const { createApp, ref } = window.Vue;
const count = ref(0);
createApp({
setup() {
return { count };
}
}).mount(__script.nextElementSibling);
}
// ... waits for Vue to be available
})(document.currentScript);
魔法在于变量提取。它会解析 const、let、var 声明并自动返回给模板。你写普通代码,它负责其余部分。
安装
composer require brunoabpinto/vector
在 app.js 中全局暴露 Vue:
import * as Vue from "vue";
window.Vue = Vue;
更新 vite.config.js 以使用 Vue 的运行时编译器:
resolve: {
alias: {
'vue': 'vue/dist/vue.esm-bundler.js',
},
},
权衡
适合
- 快速的交互式元素
- 原型设计
- 想要 Vue API 但不想要 Vue 繁琐的场景
- 主要是服务器渲染、只有少量响应式岛屿的 Laravel 应用
不太适合
- 复杂的组件层级
- 完整的 SFC 功能(作用域样式等)
- 大型 SPA(使用 Inertia 或完整的 Vue 设置)
多个组件?没问题
每个 @vector 块都是独立的:
@vector
const name = ref('World');
@endvector
Hello, @{{ name }}!
@vector
const items = ref(['Apple', 'Banana']);
const count = computed(() => items.value.length);
@endvector
- @{{ item }}
@{{ count }} items
这会不会很怪?
有一点是的。我们本质上是在运行时编译 Vue 模板,这违背了“提前编译所有内容”的理念。但有时候合适的工具就是那个不妨碍你的工具。当你只想在 Blade 视图中拥有一个响应式计数器,而不想启动完整的组件生态时,Vector 正好满足需求。
试一试
该包已在 GitHub 上发布。给它加星、fork,或者告诉我你的想法。
composer require brunoabpinto/vector