Vue 3 迁移到 Lyt.js: 完整步骤与代码实践
对于已经在使用 Vue 3 的团队来说,Lyt.js 的吸引点在于更小的包体积(约 35KB vs Vue 3 的 44KB)、可选的 Signal 模式以及未来无 VDOM 的 Vapor 模式。Lyt.js 的 API 设计大量借鉴了 Vue 3,迁移成本比想象中低很多。以下从安装到路由的整套迁移流程,附带代码对比和注意事项。## 一、核心 API 对比概览
| 概念 | Vue 3 | Lyt.js |
|---|---|---|
| 创建应用 | createApp(App) | createApp(App) |
| 定义组件 | defineComponent({...}) | defineComponent({...}) |
| 响应式数据 | reactive() / ref() | reactive() / signal() |
| 计算属性 | computed(() => ...) | computed(() => ...) |
| 侦听器 | watch() / watchEffect() | watch() / effect() |
| 生命周期 | onMounted() 等 | onMounted() 等 |
| 挂载 | app.mount('#app') | app.mount('#app') |
主要区别:ref() 在 Lyt.js 中对应 signal()(Signal 模式),如果使用 Proxy 模式则 reactive() 用法一致。
## 二、迁移步骤
### 1. 安装与卸载
# 卸载 Vue 相关包
npm uninstall vue @vue/compiler-sfc @vue/runtime-dom
# 安装 Lyt.js(无需额外安装 SFC 编译器,框架内置)
npm install @lytjs/core
Lyt.js 包结构更简洁,不需要 @vue/compiler-sfc 等额外依赖。
### 2. 修改入口文件
将 import 来源从 'vue' 改为 '@lytjs/core',文件后缀从 .vue 改为 .lyt。
// Vue 3 入口
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
// Lyt.js 入口
import { createApp } from '@lytjs/core'
import App from './App.lyt'
createApp(App).mount('#app')
### 3. 模板语法迁移
这是改动最大的部分,但模式统一:去掉 v- 前缀和 @ 符号,使用更统一的关键字。
| 功能 | Vue 3 | Lyt.js |
|---|---|---|
| 条件渲染 | v-if / v-else-if / v-else | if / else-if / else |
| 列表渲染 | v-for="item in list" | each="item in list" |
| 双向绑定 | v-model="value" | model="value" |
| 事件绑定 | @click="handle" | on:click="handle" |
| 属性绑定 | :class="cls" | :class="cls"(不变) |
| 插槽 | <slot /> | <slot />(不变) |
| 组件引用 | <MyComponent /> | <MyComponent />(不变) |
示例:
<!-- Vue 3 写法 -->
<div class="container">
<input v-model="searchText" placeholder="Search..." />
<button @click="search">Search</button>
<ul v-if="results.length > 0">
<li v-for="item in results" :key="item.id"
:class="{ active: item.active }"
@click="select(item)">
{{ item.name }}
</li>
</ul>
<p v-else>No results found.</p>
</div>
<!-- Lyt.js 写法 -->
<div class="container">
<input model="searchText" placeholder="Search..." />
<button on:click="search">Search</button>
<ul if="results.length > 0">
<li each="item in results" :key="item.id"
:class="{ active: item.active }"
on:click="select(item)">
{{ item.name }}
</li>
</ul>
<p else>No results found.</p>
</div>
改动点:v-if → if,v-for → each,@click → on:click,v-model → model。
### 4. 组件定义(Options API)
唯一变化:data() 改为 state()。
// Vue 3
import { defineComponent } from 'vue'
export default defineComponent({
name: 'MyComponent',
props: { title: String },
emits: ['update'],
data() { return { count: 0 } },
computed: {
double() { return this.count * 2 }
},
methods: {
increment() { this.count++; this.$emit('update') }
},
mounted() { console.log('mounted') }
})
// Lyt.js
import { defineComponent } from '@lytjs/core'
export default defineComponent({
name: 'MyComponent',
props: { title: String },
emits: ['update'],
state() { return { count: 0 } },// data → state
computed: {
double() { return this.count * 2 }
},
methods: {
increment() { this.count++; this.$emit('update') }
},
mounted() { console.log('mounted') }
})
### 5. Composition API 迁移
使用 Proxy 模式时,只需将 ref() 换成 reactive(),并注意从 @lytjs/core 导入。
// Vue 3 Composition API
import { ref, computed, onMounted } from 'vue'
export default {
setup() {
const count = ref(0)
const double = computed(() => count.value * 2)
const increment = () => count.value++
onMounted(() => console.log('mounted'))
return { count, double, increment }
}
}
// Lyt.js (Proxy 模式)
import { reactive, computed, onMounted } from '@lytjs/core'
export default {
setup() {
const state = reactive({ count: 0 })
const double = computed(() => state.count * 2)
const increment = () => state.count++
onMounted(() => console.log('mounted'))
return { ...state, double, increment }
}
}
若想使用 Lyt.js 提供的 Signal 模式(性能敏感场景推荐):
// Lyt.js (Signal 模式)
import { signal, computed, effect } from '@lytjs/reactivity/signal'
export default {
setup() {
const count = signal(0)
const double = computed(() => count() * 2)
const increment = () => count.update(n => n + 1)
effect(() => console.log('mounted'))
return { count, double, increment }
}
}
注意:Signal 模式下 count 是一个函数,调用 count() 获取值,通过 update 方法更新。
### 6. 路由迁移
Lyt.js 内置 router 模块,API 与 Vue Router 几乎一致。
// Vue Router
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes: [{ path: '/', component: Home }]
})
// Lyt.js Router
import { createRouter, createWebHistory } from '@lytjs/router'
const router = createRouter({
history: createWebHistory(),
routes: [{ path: '/', component: Home }]
})
## 三、迁移检查清单
- 入口文件:import 从 'vue' 改为 '@lytjs/core'
- 文件后缀:.vue → .lyt
- 模板指令:v-if → if, v-for → each, v-model → model, @click → on:click
- 组件选项:data() → state()
- Composition API:ref() → reactive() 或 signal()
- 路由:vue-router → @lytjs/router
- 构建工具:Vite 插件从 @vitejs/plugin-vue 改为 Lyt.js 编译器
- TypeScript:使用 Lyt.js VSCode 扩展获得 .lyt 文件类型支持
## 四、迁移后的收益
- 包体积减少约 20%(~35KB vs ~44KB,含编译器)
- 可切换到 Signal 模式提升性能敏感组件
- 未来可启用 Vapor Mode(无 VDOM 渲染)
- 零第三方依赖,降低安全风险
- 模板语法更简洁
## 五、常见问题解答
Q: Vuex/Pinia 状态管理怎么迁移?
A: Lyt.js 内置 provide/inject 结合 reactive/signal 即可实现全局状态管理。复杂场景参考官方文档中的状态管理最佳实践。
Q: Vue 生态 UI 库(如 Element Plus、Ant Design Vue)能用吗?
A: 目前不能直接使用。但 Lyt.js 模板语法与 HTML 完全兼容,可以使用任何原生 HTML/CSS 方案,或等待社区适配。
Q: SSR 怎么迁移?
A: Lyt.js 内置 SSR 渲染器,API 类似 Vue 3。主要调整服务端入口文件,客户端 hydrate 逻辑基本一致。
Q: 遇到问题怎么办?
A: Lyt.js 提供 VitePress 文档站,可以在 GitHub 或 Gitee 仓库提交 Issue。
## 六、总结
从 Vue 3 迁移到 Lyt.js 主要涉及三点修改:import 路径变更、模板指令简化(去掉 v- 前缀)、data() 改为 state()。其余 API、开发模式、组件化思想完全一致,熟悉 Vue 3 的开发者通常只需要几小时即可完成。迁移后获得零依赖架构和 Signal/Vapor 性能加成,对新建项目或需要精简体积的项目来说是值得的选择。
Re: Vue 3 迁移到 Lyt.js: 完整步骤与代码实践
很详细的迁移指南,感谢分享。我最近也在评估从 Vue 3 切换到 Lyt.js,有几个疑问想请教:像 Vue Router 和 Pinia 这类生态库,Lyt.js 有对应的官方方案吗?迁移时有没有遇到第三方组件库(比如 Element Plus)兼容性问题?另外 Vapor 模式现在能直接用吗,还是需要等正式版?Re: Vue 3 迁移到 Lyt.js: 完整步骤与代码实践
感谢楼主的详细分享!这个对比表非常清晰,看起来迁移工作量确实比想象中少很多。我比较关心的是,Lyt.js 对组合式 API 的支持情况怎么样?比如 setup 函数、composition functions 这些在 Lyt.js 里怎么对应?还有 Vue Router 和 Pinia 这类生态库,有没有迁移指南或者替代方案?希望楼主能继续分享这方面的经验。Re: Vue 3 迁移到 Lyt.js: 完整步骤与代码实践
感谢分享,非常详尽的迁移指南。看起来 Lyt.js 在 API 设计上确实与 Vue 3 高度相似,改动的部分也很清晰。想问一下,实际迁移过程中有没有遇到任何 Vue 3 特有的生态依赖(比如 vue-router、vuex/pinia)需要特殊处理?Lyt.js 是否有对应的路由和状态管理方案,还是需要自己适配?
页:
[1]