放假不停歇,趁着假期学习下VUE3相关的内容,一方面是自己保持活力,另一方面也是工作需要,本系列是我的自学教程,如果有从0开始学习VUE3的,可以跟着一起练习下,毕竟前端我也是泥腿子出身,这一系列会使用Vite、TS、Pinia、Element-Plus等新知识点,既是查漏补缺,也是知识分享。
代码地址:
https://github.com/anjoy8/bcvp.vue3.git
这是每篇文章一节课一个分支,方便大家学习,会慢慢的将blog.admin项目进行翻新,使用的后端接口还是BlogCore。
通常,开发VUE3因为涉及到Vite等新构建工具,所以使用node的版本>v18.12。
Vite 是一个前端构建工具,旨在加快开发和构建现代 Web 应用程序。它的名字来源于法语中的“快”(vite),其设计目标就是提高开发速度。Vite 由 Vue.js 的作者尤雨溪(Evan You)开发,但它并不仅限于 Vue.js,也支持其他框架如 React、Svelte、Preact 等。
如果还有vue2的项目,需要向下兼容低版本的VUE项目,可以用nvm工具来快速切换,还是比较好用的:
切换到v18.13后,就可以全局安全vue了:
可以看到提示,安装完成,可以开始初始化项目了。
执行项目初始化命令:
npm init vue@latest
项目名称小写,然后使用ts语法,使用jsx支持,引入Pinia状态管理,最后还引入Vue的DevTools7扩展用于调试。
还有两个没勾选,分别是:
ESLint是一个插件化的JavaScript代码检查工具,用于识别和报告JavaScript代码中的模式,以确保代码质量。
Prettier是一个自动格式化代码的工具。
直接运行新生成的项目,执行npm install安装依赖,然后执行npm run dev运行项目:
可以看到只需要1秒多即可运行项目,这就是得益于vite的好处
Vite 的主要特点:
1、极速启动:Vite 通过原生 ES 模块(ESM)的支持,在开发时可以直接利用浏览器的原生功能加载模块。这意味着项目无需预先打包,Vite 可以在启动时立即提供服务,而不需要等待整个项目的构建完成。这与传统工具如 Webpack、Parcel 等需要先打包所有依赖再启动形成了鲜明对比。
2、按需编译:传统的构建工具通常会对整个项目进行打包编译,即使只修改了一个文件。而 Vite 采用了一种即时编译的方式:只有在浏览器请求某个模块时,Vite 才会编译和传递该模块。这极大减少了开发过程中编译的时间,尤其是在大型项目中。
3、热模块替换(HMR):Vite 提供了超快的热模块替换功能,当你修改代码时,浏览器可以立即更新视图,且不会刷新整个页面。相比于传统构建工具,Vite 的 HMR 更加高效,因为它只会替换变化的模块。
4、更快速地构建:Vite 在生产环境下使用 Rollup 进行打包。Rollup 的优势在于它对 ES 模块的支持非常好,同时生成的包体积相对较小。因此,Vite 不仅在开发阶段有很好的性能,在生产阶段的构建速度和优化上也表现优异。
5、插件生态:Vite 具有丰富的插件系统,且兼容 Rollup 的插件。这意味着开发者可以方便地扩展 Vite 的功能,且其插件生态系统已经非常成熟,支持各种需求。
Vite 的优势:
1、启动速度快:特别是对于大型项目,Vite 的启动速度相对传统工具有明显的提升,因为它避免了预打包的过程。
2、开发体验好:HMR 更加高效,修改后的内容几乎可以立即反映在浏览器中,提升了开发者的效率。
3、轻量化:Vite 的设计理念更贴近现代浏览器环境,利用 ES 模块的原生支持,从根本上简化了构建流程。
4、生态系统健全:Vite 支持多种框架和库,并且有插件机制可以进行功能扩展。
5、现代化:相比传统工具,它从设计上就更加符合现代开发的需求。
直接访问项目地址You dit it!你做到啦,查看效果,动图如下:
可以看到页面的最下边有一个小图标,可以方便调试,也有Pinia相关的状态管理,然后还能看到状态图,从main.ts作为入口,其实准确来说就是组件引用图:
整体项目结构就是这样的:
和之前的vue2还是比较类型的,最大的差异就是vue实例的生成和ts语言的引入。
初始化的项目依赖也很少:
在 Vue 3 中,Pinia 是一种用于状态管理的库,类似于 Vue 2 中的 Vuex。它的主要作用是帮助你在应用中管理全局状态,尤其是当你在多个组件之间共享数据时,Pinia 提供了一个更简洁、更现代化的方式来管理这些数据。
Pinia 的特点和作用:
1、状态管理:Pinia 用于在组件之间共享数据和状态,它允许你集中管理应用的状态,从而使代码更加模块化和易于维护。
2、模块化:与 Vuex 类似,Pinia 也支持模块化的设计。你可以将状态拆分到不同的 Store 中,使状态管理更加清晰。
3、轻量且性能更好:Pinia 相较于 Vuex 更加轻量,并且充分利用了 Vue 3 的 Composition API 和 Proxy,对性能进行了优化。
4、开发体验更好:Pinia 支持热重载和 TypeScript 类型推断,这意味着你可以在开发时享受更好的工具支持和调试体验。
5、与 Vue DevTools 集成:Pinia 也可以与 Vue DevTools 一起使用,使得调试应用状态更加方便。
在stores文件夹下,新增counter.ts,做一个计数的状态管理。
然后在HomeView.vue文件中,引用刚刚的状态管理计数器:
扩展建议:在 Vue 2 中,Vuex 是官方推荐的状态管理库,而在 Vue 3 中,虽然 Vuex 依然可以使用,但 Pinia 被认为是更加现代化的替代方案。它提供了更简洁的 API,适合在 Vue 3 的生态中使用,因此在许多新项目中,Pinia 是管理全局状态的首选。
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
function increment() {
count.value++
}
return { count, doubleCount, increment }
})
当然,如果感觉上边的写法不太习惯,也可以使用vuex之前的类似的写法:
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
// 定义状态
state: () => ({
count: 0,
}),
// 定义 actions,可以包含异步操作
actions: {
increment() {
this.count++
},
decrement() {
this.count--
},
},
// 定义 getters,用来计算衍生的状态
getters: {
doubleCount: (state) => state.count * 2,
},
})
效果也是一样的
Composition API 是 Vue 3 引入的一种新的组件编写方式,使逻辑复用更加简单和直观。
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
const increment = () => {
count.value++
}
return {
count,
increment
}
}
}
</script>
然后这组组合写法还是比较麻烦,所以官方就推出了一个语法糖,解决了不少麻烦:
<script setup lang="ts">
import { computed } from 'vue'
import TheWelcome from '@/components/TheWelcome.vue'
import { useCounterStore } from "../stores/counter";
// 获取 store
const counterStore = useCounterStore()
// 使用 store 中的状态和方法,不使用解构来保持响应性
const count = computed(() => counterStore.count)
const doubleCount = computed(() => counterStore.doubleCount)
const increment = counterStore.increment
</script>
<template>
<main>
<TheWelcome />
<p>Count: {{ count }}</p>
<p>Double Count: {{ doubleCount }}</p>
<button @click="increment">Increment</button>
</main>
</template>
ref 和 reactive 都是 Vue 中用于创建响应式数据的工具,但它们的应用场景和工作方式有所不同。
1、ref 用于基本类型的数据(如字符串、数字、布尔值等),通过 let xxx = ref(初始值) 创建一个响应式对象。这个对象返回一个 RefImpl 实例,响应式的数据存储在 value 属性中,因此在 JavaScript 代码中需要通过 xxx.value 来访问和修改值;但在模板中,Vue 会自动解包 value,无需显式调用。
2、reactive 则用于对象类型的数据(如对象、数组),通过 let 响应式对象 = reactive(源对象) 创建。它返回的是一个代理(Proxy)对象,该对象的所有属性都是响应式的,任何对属性的读写操作都会触发响应式更新。
3、在实际开发中,ref 更适合处理单一的、简单的基本类型数据,而 reactive 则更适合复杂的对象和数组。尽管 ref 也可以用来处理对象,但对于复杂对象,reactive 能提供更直观的响应式行为。
4、注意点:当使用 ref 处理对象时,仍需要通过 value 属性来访问和修改对象;而使用 reactive 时,对象本身就是响应式的,直接修改其属性即可触发更新,无需额外处理。
5、区别与联系:从宏观上看,ref 更适合定义基本类型的数据,也可以定义对象类型数据;reactive 仅适用于对象类型数据。