
文章目录前言一、Vue3到底香在哪为什么现在都用它1. 性能直接拉满加载速度更快2. 源码升级对大型项目更友好3. 对TypeScript“原生拥抱”4. 新增了不少实用特性二、手把手上手用Vite创建第一个Vue3项目1. 准备环境2. 用Vite创建项目3. 写个最简单的效果三、Vue3核心语法从API到响应式一次吃透1. 先搞懂Options API vs Composition API2. 组合式API的入口setup与script setup语法糖3. 响应式核心ref和reactive怎么选① ref啥都能装简单数据首选② reactive对象/数组专用复杂数据首选③ 小技巧toRefs解决解构问题④ 怎么选给你个懒人建议4. 数据衍生与监听computed、watch和watchEffect① computed计算属性和Vue2一样好用② watch监听指定数据的变化③ watchEffect自动收集依赖不用指定监听源5. 生命周期与组件通信① Vue3的生命周期② 组件通信props、emit和ref6. 逻辑复用神器自定义Hook前言咱做前端的没人绕得开Vue。从Vue2一路用到Vue3我刚上手时也被一堆新API搞晕过——setup、ref、reactive到底怎么用Composition API比Options API好在哪今天就把我踩过坑、捋顺了的Vue3入门干货一次性分享给你看完就能上手写项目一、Vue3到底香在哪为什么现在都用它Vue3不是简单的“加了几个新功能”而是一次从内到外的全面重构解决了不少Vue2的痛点也更适配现在的大型项目和TypeScript生态。1. 性能直接拉满加载速度更快Vue2的响应式基于Object.defineProperty不仅对数组的监听有局限编译时也没法做太多优化。Vue3直接换了底层用Proxy重写了响应式系统能监听对象的增删改数组的变化也能完美捕捉编译时做了静态提升、PatchFlag标记渲染时只更新真正变化的部分复杂场景下性能比Vue2快了一倍不止打包体积还小了不少。2. 源码升级对大型项目更友好Vue2的早期源码没怎么考虑模块化后期维护起来很麻烦。Vue3用TypeScript重写了整个源码把功能拆成了独立的模块比如响应式、虚拟DOM、编译器不仅维护更方便也让我们写项目时能用上完整的类型推断减少类型错误。3. 对TypeScript“原生拥抱”Vue2里用TS总感觉“隔了一层”很多类型推断都不好用。Vue3从底层就支持TS不管是组件定义还是API调用都能享受到完整的类型提示写大型项目时再也不用靠猜变量类型了。4. 新增了不少实用特性除了大家常说的Composition APIVue3还加了很多好用的功能比如跨层级渲染的Teleport、处理异步组件的Suspense、更灵活的Fragment不用再写根节点了还有全局API改成了应用实例API避免了全局污染。二、手把手上手用Vite创建第一个Vue3项目创建Vue3项目有两种主流方式vue-cli和Vite咱直接推荐Vite——比vue-cli快了不止一星半点现在几乎是Vue项目的标配了。1. 准备环境先确保你电脑上装了Node.js推荐16版本打开终端就能用npm命令了。2. 用Vite创建项目终端里直接敲这行命令npmcreate vitelatest my-vue3-project ----templatevue-tsmy-vue3-project是你的项目名随便改vue-ts代表用Vue3TypeScript模板不想用TS的话改成vue就行。跟着提示走进入项目文件夹、安装依赖、启动项目cdmy-vue3-projectnpminstallnpmrun dev终端会给你一个本地地址打开浏览器就能看到Vue3的默认页面了是不是超简单3. 写个最简单的效果打开src/App.vue把默认内容删掉写个计数器试试template div classapp h1Vue3入门计数器/h1 p当前计数{{ count }}/p button clickaddCount点我1/button /div /template script setup langts import { ref } from vue // 定义响应式数据 const count ref(0) // 定义方法 const addCount () { count.value } /script style scoped .app { text-align: center; margin-top: 50px; } button { padding: 8px 16px; font-size: 16px; cursor: pointer; } /style保存一下浏览器里点按钮数字会跟着变你的第一个Vue3组件就跑起来了三、Vue3核心语法从API到响应式一次吃透这部分是Vue3的灵魂咱不用死记硬背API跟着场景学搞懂每个东西什么时候用就行。1. 先搞懂Options API vs Composition API你写Vue2时肯定熟悉这种写法script export default { data() { return { count: 0 } }, methods: { addCount() { this.count } }, computed: {}, watch: {} } /script这就是Options API按“数据、方法、计算属性”这些选项分类写小项目看着很清晰但组件大了就会很痛苦——同一个功能的代码要散在data、methods、watch里找起来麻烦逻辑复用还要靠mixin很容易出问题。Vue3主推的Composition API就是为了解决这个问题它不按选项拆分而是按“业务逻辑”聚合代码同一个功能的所有数据、方法、监听都写在一起复用起来也方便。比如上面的计数器用Composition API写就是script setup langts import { ref } from vue // 计数器逻辑数据方法都写在一起 const count ref(0) const addCount () { count.value } /script逻辑一目了然后续要加个“重置计数”的功能直接在这堆代码里加就行不用跑到别的选项里找。2. 组合式API的入口setup与script setup语法糖setup是Composition API的“舞台”所有响应式API都要在setup里用。Vue3.2之后出了script setup语法糖现在几乎所有项目都用它比原生setup简洁太多不用写export default不用手动return变量模板里直接用内置了defineProps、defineEmits这些API不用额外导入天生支持TypeScript类型提示更友好。比如父子组件传值用script setup写超简单!-- 子组件 Child.vue -- template p收到父组件的消息{{ parentMsg }}/p button clicksendMsg给父组件发消息/button /template script setup langts // 接收父组件传的props const props defineProps{ parentMsg: string }() // 定义自定义事件给父组件传值 const emit defineEmits([sendMsg]) const sendMsg () { emit(sendMsg, 我收到消息啦) } /script3. 响应式核心ref和reactive怎么选写Vue绕不开响应式Vue3给了两个核心APIref和reactive很多新手刚上手分不清其实很简单① ref啥都能装简单数据首选ref可以处理所有类型的数据基本类型数字、字符串、布尔和对象/数组都能装返回一个响应式对象修改时要加.value模板里会自动解包不用写.value。script setup langts import { ref } from vue // 基本类型 const count ref(0) // 对象类型也能装 const user ref({ name: 张三, age: 18 }) const update () { count.value // JS里要写.value user.value.name 李四 // 修改对象也要.value } /script template p{{ count }}/p !-- 模板里不用.value -- p{{ user.name }}/p /template② reactive对象/数组专用复杂数据首选reactive只能处理对象、数组这类引用类型不用写.value直接修改属性就行天生就是深度响应式嵌套的对象属性修改也能触发更新。script setup langts import { reactive } from vue // 多层嵌套的表单对象 const form reactive({ username: , password: , address: { city: 北京 } }) // 直接修改属性不用.value const updateCity () { form.address.city 上海 } /script⚠️ 注意reactive不能直接整体赋值比如form reactive({})会丢失响应式要用Object.assign(form, 新对象)来更新。③ 小技巧toRefs解决解构问题如果想解构reactive对象直接解构会丢失响应式这时候用toRefsscript setup langts import { reactive, toRefs } from vue const user reactive({ name: 张三, age: 18 }) // 解构后还是响应式的 const { name, age } toRefs(user) // 修改时还是要.value name.value 李四 /script④ 怎么选给你个懒人建议单个简单数据比如计数器、开关状态直接用ref表单、配置、多层嵌套的对象/数组直接用reactive纠结的时候用ref也不会错ref装对象内部也会自动调用reactive。4. 数据衍生与监听computed、watch和watchEffect① computed计算属性和Vue2一样好用和Vue2的computed功能差不多用来根据其他响应式数据衍生新数据自带缓存依赖变了才会重新计算script setup langts import { ref, computed } from vue const count ref(0) // 计算属性count的两倍 const doubleCount computed(() count.value * 2) /script template pcount: {{ count }}/p pcount的两倍{{ doubleCount }}/p /template② watch监听指定数据的变化想监听某个响应式数据的变化用watch比如监听用户输入script setup langts import { ref, watch } from vue const keyword ref() // 监听keyword变化做搜索 watch(keyword, (newVal, oldVal) { console.log(用户输入了, newVal) // 这里可以调用搜索接口 }, { immediate: true }) // immediate表示组件挂载时就执行一次 /script如果要监听reactive对象里的某个属性或者多个数据也可以传数组用法很灵活。③ watchEffect自动收集依赖不用指定监听源watchEffect不用手动指定要监听谁它会自动收集你用到的响应式数据数据变了就重新执行函数适合做副作用比如更新文档标题script setup langts import { ref, watchEffect } from vue const count ref(0) // 自动收集count作为依赖count变了就执行 watchEffect(() { document.title 当前计数${count.value} }) /script5. 生命周期与组件通信① Vue3的生命周期Vue3的生命周期和Vue2差不多只是在setup里要用函数式的写法比如script setup langts import { onMounted, onUpdated, onUnmounted } from vue // 组件挂载后执行相当于Vue2的mounted onMounted(() { console.log(组件挂载了发请求拿数据) }) // 组件更新后执行相当于updated onUpdated(() { console.log(组件更新了) }) // 组件卸载前执行相当于beforeDestroy onUnmounted(() { console.log(组件卸载了清理定时器) }) /script② 组件通信props、emit和ref父传子用defineProps刚才已经写过例子了子传父用defineEmits触发事件父组件拿子组件实例用refdefineExpose!-- 子组件 Child.vue -- script setup langts const msg 我是子组件的数据 // 暴露给父组件的属性/方法 defineExpose({ msg }) /script !-- 父组件 App.vue -- template Child refchildRef / /template script setup langts import { ref, onMounted } from vue import Child from ./Child.vue const childRef ref() onMounted(() { // 挂载后就能拿到子组件暴露的数据了 console.log(childRef.value.msg) // 输出我是子组件的数据 }) /script6. 逻辑复用神器自定义HookVue3最香的一点就是可以把重复的逻辑抽成自定义Hook比如多个组件都要用的“本地存储”“计数器”逻辑抽成Hook后直接用就行不用每个组件都写一遍。比如写个简单的计数器Hook// hooks/useCounter.tsimport{ref}fromvueexportfunctionuseCounter(initialValue0){constcountref(initialValue)constadd()count.valueconstsubtract()count.value--constreset()count.valueinitialValuereturn{count,add,subtract,reset}}在组件里直接用script setup langts import { useCounter } from ./hooks/useCounter // 直接拿到所有逻辑不用在组件里写重复代码 const { count, add, subtract, reset } useCounter(10) /script这样组件里的代码就清爽多了逻辑复用也超方便再也不用写一堆重复的代码了。