1. 为什么要学 Vue3
1.1 为什么要学 Vue3
1.2 Vue3的优势
1.3 Vue2 选项式 API vs Vue3 组合式AP
![](https://i-blog.csdnimg.cn/direct/83a3cf321bbf4011a7e4e5eb8b54cd76.png)
2. create-vue搭建Vue3项目
2.1 认识 create-vue
![](https://i-blog.csdnimg.cn/direct/62daada52b42458a95d244e7f04a0bac.png)
2.2 使用create-vue创建项目
- 已安装 16.0 或更高版本的 Node.js
- node -v
- npm init vue@latest
- 这一指令将会安装并执行 create-vue(vue@latest: 这是一个指定要使用的包(vue)的名称和版本(latest 表示最新版本))
- 避免了之前创建项目使用
npm init vite-app 项目名称
或者yarn create vite-app 项目名称,版本不兼容的问题。
- 输入项目名称
2.3 vue2和vue3中 vscode 快捷插件
- vue2.0
- vue3.0
3. 熟悉项目目录和关键文件
3.1 项目目录和关键文件
① vite.config.js - 项目的配置文件 基于vite的配置
② package.json - 项目包文件 核心依赖项变成了 Vue3.x 和 vite
③ main.js - 入口文件 createApp函数创建应用实例
④ app.vue - 根组件 SFC单文件组件 script - template - style
- 变化一:脚本script和模板template顺序调整
- 变化二:模板template不再要求唯一根元素
- 变化三:脚本script添加setup标识支持组合式API
⑤ index.html - 单页入口 提供id为app的挂载点
4. 组合式API - setup选项
4.1 setup选项的写法和执行时机
- 执行时机,比 beforeCreate 还要早
- setup 函数中,获取不到 this (this 的值为 undefined)
- 数据和函数,需要在 setup 最后 return,才能在模版中应用
- 每次都要去 return 太麻烦
- 通过 setup 语法糖简化代码
4.2 setup选项中写代码的特点
4.3 <script setup> 语法糖
- 原始复杂写法
- 语法糖写法
4.4 <script setup> 语法糖原理
4.5 总结
- setup选项的执行时机?
- beforeCreate钩子之前 自动执行
- setup写代码的特点是什么?
- 定义数据 + 函数 然后以对象方式return
- <script setup>解决了什么问题?
- 经过语法糖的封装更简单的使用组合式API
- setup中的this还指向组件实例吗?
- 指向undefined
5. 组合式API - reactive和ref函数
5.1 reactive()
作用:接受对象类型数据的参数传入并返回一个响应式的代理对象(Proxy(Object))
![](https://i-blog.csdnimg.cn/direct/602bf8fea44f4e078a4d1caaeed104d2.png)
5.2 ref()
![](https://i-blog.csdnimg.cn/direct/c07ba07ffea6465a87e1813897dc28bc.png)
5.3 总结
- reactive和ref函数的共同作用是什么 ?
- 用函数调用的方式生成响应式数据
- reactive vs ref ?
- reactive不能处理简单类型的数据
- ref参数类型支持更好但是必须通过.value访问修改
- ref函数的内部实现依赖于reactive函数
- 在实际工作中推荐使用哪个?
- 推荐使用ref函数,更加灵活统一
6. 组合式API - computed
6.1 computed计算属性函数
计算属性基本思想和Vue2的完全一致,组合式API下的计算属性只是修改了写法
![](https://i-blog.csdnimg.cn/direct/14f756898c2e4f52a44f082e23879cf3.png)
6.2 计算属性小案例
![](https://i-blog.csdnimg.cn/direct/478234da2a844931baf166c353029e29.png)
6.3 计算属性 get 和 set
![](https://i-blog.csdnimg.cn/direct/b988e773f5d4499c9e982d78798559a2.png)
6.4 总结
- 计算属性中不应该有“副作用”
- 比如异步请求/修改dom
- 避免直接修改计算属性的值
- 计算属性应该是只读的,特殊情况可以配置 get set
7. 组合式API - watch
7.1 watch函数
7.2 基础使用 - 侦听单个数据
![](https://i-blog.csdnimg.cn/direct/0475a1be90b34be1a641f1ab675485fc.png)
7.3 基础使用 - 侦听多个数据
![](https://i-blog.csdnimg.cn/direct/f2413ba4999b484288b8ee59919b4b46.png)
7.4 immediate
![](https://i-blog.csdnimg.cn/direct/5a1d256acc0843058435a9ad3c49df95.png)
7.5 deep
![](https://i-blog.csdnimg.cn/direct/1e6da7aba63740368ecb99933da07cc6.png)
![](https://i-blog.csdnimg.cn/direct/a2200066be5944abab35a8cac37c4847.png)
7.6 精确侦听对象的某个属性
![](https://i-blog.csdnimg.cn/direct/85365c3475d54cd4bfdaa6ffbe577a6e.png)
7.7 总结
- 作为watch函数的第一个参数,ref对象需要添加.value吗?
- 不需要,第一个参数就是传 ref 对象
- watch只能侦听单个数据吗?
- 单个 或者 多个
- 不开启deep,直接监视 复杂类型,修改属性 能触发回调吗?
- 不能,默认是浅层侦听
- 不开启deep,精确侦听对象的某个属性?
- 可以把第一个参数写成函数的写法,返回要监听的具体属性
8. 组合式API - 生命周期函数
8.1 Vue3的生命周期API (选项式 VS 组合式)
8.2 生命周期函数基本使用
![](https://i-blog.csdnimg.cn/direct/848d71beb32f49438afea4c7ff2c0f3c.png)
8.3 执行多次
![](https://i-blog.csdnimg.cn/direct/485d8092607d497a95875d1abfb36aa1.png)
8.4 总结
- 组合式API中生命周期函数的格式是什么?
- on + 生命周期名字
- 组合式API中可以使用onCreated吗?
- 没有这个钩子函数,直接写到setup中
- 组合式API中组件卸载完毕时执行哪个函数?
- onUnmounted
9. 组合式API - 父子通信
9.1 组合式API下的父传子
- 原始写法不使用<script setup> 语法糖
父组件:
子组件:
- <script setup> 语法糖写法
父组件:
子组件:
-
由于写了 setup 糖果语法,所以无法直接配置 props 选项
-
子组件中通过 编译宏 defineProps 接收属性
-
编译宏只能在一个组件中各定义一次,不能重复定义。
![](https://i-blog.csdnimg.cn/direct/d7744ece53094dc58752527d8e351226.png)
9.2 组合式API下的子传父
- 原始写法不使用<script setup> 语法糖
父组件:
子组件:
- setup 里接收两参数,一个是 props 属性,一个是 context 上下文
props
参数包含了从父组件传递给当前子组件的所有属性。它是一个响应式对象,这意味着当父组件中的属性值发生变化时,props
中对应的值也会自动更新。context
参数是一个包含了当前组件上下文的对象。它包括attrs
、slots
和emit
等属性。这些属性为组件提供了访问父组件传递的非props
属性、插槽内容以及触发事件的方法。
- <script setup> 语法糖写法
父组件
子组件:
9.3 总结
父传子
- 父传子的过程中通过什么方式接收props?
- defineProps( { 属性名:类型 } )
- setup语法糖中如何使用父组件传过来的数据?
- const props = defineProps( { 属性名:类型 } )
- props.xxx
子传父
- 子传父的过程中通过什么方式得到emit方法?
- defineEmits( [‘事件名称’] )
- 怎么触发事件
- emit('自定义事件名' , 参数)
10. 组合式API - 兄弟组件之间通信
10.1 vue2.0兄弟组件间通信——eventBus
① src/EventBus/index.js – 创建空白Vue对象并导出
② 在要传递值的组件
eventBus.$emit('事件名', 值)
③ 在要接收值的组件的Create生命周期里
eventBus.$on('事件名', 函数体)
10.2 组合式API - 兄弟组件之间通信——mitt
① 下载安装 mitt 库
- npm install mitt 或者 yarn add mitt
② src/EventBus/index.js – 创建空白mitt对象并导出
10
③ 在要传递值的组件
eventBus.emit('事件名', 值)
④ 在要接收值的组件
eventBus.on('事件名', 函数体)
11. 组合式API - 模版引用
11.1 模板引用的概念
11.2 如何使用(以获取dom为例 组件同理)
![](https://i-blog.csdnimg.cn/direct/95a5910e96fc497780fe641195c89ade.png)
11.3 defineExpose()
① 如果子组件未使用<script setup>语法糖,子组件内部的属性和方法,父组件可以访问到。所有需要暴露给模板或父组件的方法和属性都通过 return
返回出来了。(setup () { return })
- 子组件中定义了count 和 sayHi 方法
- 通过模版引用父组件可以拿到 count 和 sayHi 方法
- 子组件中通过 defineExpose编译宏暴露 count 和 sayHi 方法
![](https://i-blog.csdnimg.cn/direct/3e61816b185547f5963fdd91ccb1ad22.png)
- 通过模版引用父组件可以拿到 count 和 sayHi 方法
11.4 总结
- 获取模板引用的时机是什么?
- 组件挂载完毕
- defineExpose编译宏的作用是什么?
- 显式暴露组件内部的属性和方法
12. 组合式API - provide和inject
12.1 作用和场景
![](https://i-blog.csdnimg.cn/direct/cdfa2dff138c44b8bd604502387cae28.png)
vue2.0中的 provide 和 inject
12.2 跨层传递普通数据
![](https://i-blog.csdnimg.cn/direct/c1a2c14eb68f4f05ada37a2cc95c4a7c.png)
12.3 跨层传递响应式数据
![](https://i-blog.csdnimg.cn/direct/d11d2e7c8e614f4a8002f047502c6379.png)
12.4 总结
- provide 和 inject 的作用是什么?
- 跨层组件通信
- 如何在传递的过程中保持数据响应式?
- 第二个参数传递ref对象
- 底层组件想要通知顶层组件做修改,如何做?
- 传递方法,底层组件调用方法
- 一颗组件树中只有一个顶层或底层组件吗?
- 相对概念,存在多个顶层和底层的关系
13. Vue3.3新特性-defineOptions
- 有 <script setup> 之前,如果要定义 props, emits 可以轻而易举地添加一个与 setup 平级的属性。
- 但是用了 <script setup> 后,就没法这么干了 setup 属性已经没有了,自然无法添加与其平级的属性。
- 为了解决这一问题,引入了 defineProps 与 defineEmits 这两个宏。但这只解决了 props 与 emits 这两个属性。
- 如果我们要定义组件的 name 或其他自定义的属性,还是得回到最原始的用法——再添加一个普通的 <script> 标签。 这样就会存在两个 <script> 标签。让人无法接受。
所以在 Vue 3.3 中新引入了 defineOptions 宏。顾名思义,主要是用来定义 Options API 的选项。可以用 defineOptions 定义任意的选项, props, emits, expose, slots 除外(因为这些可以使用 defineXXX 来做到)
14. Vue3.3新特性-defineModel(了解,不常用)
14.1 在vue2.0中v-mode语法糖简写的代码
v-model用于组件上
父组件:
子组件:
- 当输入框的内容发生变化时(即触发 @input事件),子组件会触发($emit)一个名为 input 的自定义事件,并将输入框的当前值作为事件参数传递给父组件。
14.4 Vue3 中的 v-model 和 defineModel
![](https://i-blog.csdnimg.cn/direct/5fe025a3565549bca148b6c2cd13b925.png)