写在前面
本文为尚硅谷禹神 Vue3 教程的学习笔记。本着自己学习、分享他人的态度,分享学习笔记,希望能对大家有所帮助。推荐先按顺序阅读往期内容:\
1. Vue3 学习笔记(Day1)
::: block-1
目录
3 Vue3 核心语法
- 3.1 选项式API 与 组合式API
- 3.2 setup
- 3.3 ref 和 reactive
- 3.4 computed
- 3.5 watch
- 3.6 标签的 ref 属性
- 3.7 props
- 3.8 生命周期
- 3.9 hook
:::
3 Vue3 核心语法
3.1 选项式API 与 组合式API
P6:https://www.bilibili.com/video/BV1Za4y1r7KE?p=6
Vue2
的API
设计是Options
(选项式)风格的。Vue3
的API
设计是Composition
(组合式)风格的。
Options API 的弊端:
Options
类型的 API
,数据、方法、计算属性等,是分散在:data
、methods
、computed
中的,若想新增或者修改一个需求,就需要分别修改:data
、methods
、computed
,不便于维护和复用。
:::: column
::: column-left 44.5%
:::
::: column-right 55.5%
:::
::::
Composition API 的优势:
可以用函数的方式,更加优雅的组织代码,让相关功能的代码更加有序的组织在一起。
:::: column
::: column-left 48.5%
:::
::: column-right 51.5%
:::
::::
3.2 setup
setup 概述
P7:https://www.bilibili.com/video/BV1Za4y1r7KE?p=7
setup
是Vue3
中一个新的配置项,值是一个函数,它是 Composition API
“表演的舞台”,组件中所用到的:数据、方法、计算属性、监视......等等,均配置在setup
中。
特点如下:
setup
函数返回的对象中的内容,可直接在模板中使用。setup
中访问this
是undefined
。setup
函数会在beforeCreate
之前调用,它是“领先”所有钩子执行的。
姓名:{{name}}
年龄:{{age}}
setup 的返回值
P8:https://www.bilibili.com/video/BV1Za4y1r7KE?p=8
- 若返回一个对象:则对象中的:属性、方法等,在模板中均可以直接使用(重点关注)。
- 若返回一个函数:则可以自定义渲染内容,代码如下:
setup(){
return ()=> '你好啊!'
}
setup 与 Options API 的关系
P9:https://www.bilibili.com/video/BV1Za4y1r7KE?p=9
Vue2
的配置(data
、methos
......)中可以访问到setup
中的属性、方法。- 但在
setup
中不能访问到Vue2
的配置(data
、methos
......)。 - 如果与
Vue2
冲突,则setup
优先。
setup 语法糖
P10:https://www.bilibili.com/video/BV1Za4y1r7KE?p=10
setup
函数有一个语法糖,这个语法糖,可以让我们把setup
独立出去,代码如下:
姓名:{{name}}
年龄:{{age}}
扩展:上述代码,还需要编写一个不写setup
的script
标签,去指定组件名字,比较麻烦,我们可以借助vite
中的插件简化
- 第一步:
npm i vite-plugin-vue-setup-extend -D
第二步:在
vite.config.ts
文件中添加以下内容import { defineConfig } from 'vite' import VueSetupExtend from 'vite-plugin-vue-setup-extend' export default defineConfig({ plugins: [ VueSetupExtend() ] })
- 第三步:
3.3 ref 和 reactive
ref 创建:基本类型的响应式数据
P11:https://www.bilibili.com/video/BV1Za4y1r7KE?p=11
- 作用:定义响应式变量。
- 语法:
let xxx = ref(初始值)
。 - 返回值:一个
RefImpl
的实例对象,简称ref对象
或ref
,ref
对象的value
属性是响应式的。 注意点:
JS
中操作数据需要:xxx.value
,但模板中不需要.value
,直接使用即可。- 对于
let name = ref('张三')
来说,name
不是响应式的,name.value
是响应式的。
姓名:{{name}}
年龄:{{age}}
reactive 创建:对象类型的响应式数据
P12:https://www.bilibili.com/video/BV1Za4y1r7KE?p=12
- 作用:定义一个响应式对象(基本类型不要用它,要用
ref
,否则报错) - 语法:
let 响应式对象= reactive(源对象)
。 - 返回值:一个
Proxy
的实例对象,简称:响应式对象。 - 注意点:
reactive
定义的响应式数据是“深层次”的。
汽车信息:一台{{ car.brand }}汽车,价值{{ car.price }}万
游戏列表:
- {{ g.name }}
测试:{{obj.a.b.c.d}}
ref 创建:对象类型的响应式数据
P13:https://www.bilibili.com/video/BV1Za4y1r7KE?p=13
- 其实
ref
接收的数据可以是:基本类型、对象类型。 - 若
ref
接收的是对象类型,内部其实也是调用了reactive
函数。
汽车信息:一台{{ car.brand }}汽车,价值{{ car.price }}万
游戏列表:
- {{ g.name }}
测试:{{obj.a.b.c.d}}
ref 对比 reactive
P14:https://www.bilibili.com/video/BV1Za4y1r7KE?p=14
宏观角度看:
ref
用来定义:基本类型数据、对象类型数据;reactive
用来定义:对象类型数据。
区别:
使用原则:
- 若需要一个基本类型的响应式数据,必须使用
ref
。 - 若需要一个响应式对象,层级不深,
ref
、reactive
都可以。 - 若需要一个响应式对象,且层级较深,推荐使用
reactive
。
toRefs 与 toRef
P15:https://www.bilibili.com/video/BV1Za4y1r7KE?p=15
- 作用:将一个响应式对象中的每一个属性,转换为
ref
对象。 - 备注:
toRefs
与toRef
功能一致,但toRefs
可以批量转换。 - 语法如下:
姓名:{{person.name}}
年龄:{{person.age}}
性别:{{person.gender}}
3.4 computed
P16:https://www.bilibili.com/video/BV1Za4y1r7KE?p=16
作用:根据已有数据计算出新数据(和Vue2
中的computed
作用一致)。
姓:
名:
全名:{{fullName}}
3.5 watch
P17:https://www.bilibili.com/video/BV1Za4y1r7KE?p=17
- 作用:监视数据的变化(和
Vue2
中的watch
作用一致) - 特点:
Vue3
中的watch
只能监视以下四种数据:
ref
定义的数据。reactive
定义的数据。- 函数返回一个值(
getter
函数)。 - 一个包含上述内容的数组。
我们在Vue3
中使用watch
的时候,通常会遇到以下几种情况:
情况一
监视ref
定义的【基本类型】数据:直接写数据名即可,监视的是其value
值的改变。
情况一:监视【ref】定义的【基本类型】数据
当前求和为:{{sum}}
情况二
P18:https://www.bilibili.com/video/BV1Za4y1r7KE?p=18
监视ref
定义的【对象类型】数据:直接写数据名,监视的是对象的【地址值】,若想监视对象内部的数据,要手动开启深度监视。
注意:
- 若修改的是
ref
定义的对象中的属性,newValue
和oldValue
都是新值,因为它们是同一个对象。 - 若修改整个
ref
定义的对象,newValue
是新值,oldValue
是旧值,因为不是同一个对象了。
情况二:监视【ref】定义的【对象类型】数据
姓名:{{ person.name }}
年龄:{{ person.age }}
情况三
P19:https://www.bilibili.com/video/BV1Za4y1r7KE?p=19
监视reactive
定义的【对象类型】数据,且默认开启了深度监视。
情况三:监视【reactive】定义的【对象类型】数据
姓名:{{ person.name }}
年龄:{{ person.age }}
测试:{{obj.a.b.c}}
情况四
P20:https://www.bilibili.com/video/BV1Za4y1r7KE?p=20
监视ref
或reactive
定义的【对象类型】数据中的某个属性,注意点如下:
- 若该属性值不是【对象类型】,需要写成函数形式。
- 若该属性值依然是【对象类型】,可直接编,也可写成函数,建议写成函数。
结论:监视的要是对象里的属性,那么最好写函数式,注意点:若是对象监视的是地址值,需要关注对象内部,需要手动开启深度监视。
情况四:监视【ref】或【reactive】定义的【对象类型】数据中的某个属性
姓名:{{ person.name }}
年龄:{{ person.age }}
汽车:{{ person.car.c1 }}、{{ person.car.c2 }}
情况五
P21:https://www.bilibili.com/video/BV1Za4y1r7KE?p=21
监视上述的多个数据
情况五:监视上述的多个数据
姓名:{{ person.name }}
年龄:{{ person.age }}
汽车:{{ person.car.c1 }}、{{ person.car.c2 }}
watchEffect
P22:https://www.bilibili.com/video/BV1Za4y1r7KE?p=22
官网:立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行该函数。
watch
对比watchEffect
- 都能监听响应式数据的变化,不同的是监听数据变化的方式不同
watch
:要明确指出监视的数据watchEffect
:不用明确指出监视的数据(函数中用到哪些属性,那就监视哪些属性)。
示例代码:
需求:水温达到50℃,或水位达到20cm,则联系服务器
水温:{{temp}}
水位:{{height}}
3.6 标签的 ref 属性
P23:https://www.bilibili.com/video/BV1Za4y1r7KE?p=23
作用:用于注册模板引用。
- 用在普通
DOM
标签上,获取的是DOM
节点。 - 用在组件标签上,获取的是组件实例对象。
用在普通DOM
标签上:
尚硅谷
前端
Vue
用在组件标签上:
3.7 props
回顾 TS 中的接口
P24:https://www.bilibili.com/video/BV1Za4y1r7KE?p=24
props 的使用
P25:https://www.bilibili.com/video/BV1Za4y1r7KE?p=25
type/index.ts
中代码:
// 定义一个接口,限制每个Person对象的格式
export interface PersonInter {
id:string,
name:string,
age:number
}
// 定义一个自定义类型Persons
export type Persons = Array
App.vue
中代码:
Person.vue
中代码:
-
{{item.name}}--{{item.age}}
3.8 生命周期
P26:https://www.bilibili.com/video/BV1Za4y1r7KE?p=26
概念:Vue
组件实例在创建时要经历一系列的初始化步骤,在此过程中Vue
会在合适的时机,调用特定的函数,从而让开发者有机会在特定阶段运行自己的代码,这些特定的函数统称为:生命周期钩子
规律:生命周期整体分为四个阶段,分别是:创建、挂载、更新、销毁,每个阶段都有两个钩子,一前一后。
P27:https://www.bilibili.com/video/BV1Za4y1r7KE?p=27
Vue2
的生命周期
- 创建阶段:
beforeCreate
、created
- 挂载阶段:
beforeMount
、mounted
- 更新阶段:
beforeUpdate
、updated
- 销毁阶段:
beforeDestroy
、destroyed
P28:https://www.bilibili.com/video/BV1Za4y1r7KE?p=28
Vue3
的生命周期
- 创建阶段:
setup
- 挂载阶段:
onBeforeMount
、onMounted
- 更新阶段:
onBeforeUpdate
、onUpdated
- 卸载阶段:
onBeforeUnmount
、onUnmounted
常用的钩子:onMounted
(挂载完毕)、onUpdated
(更新完毕)、onBeforeUnmount
(卸载之前)
示例代码:
当前求和为:{{ sum }}
3.9 hook
P29:https://www.bilibili.com/video/BV1Za4y1r7KE?p=29
什么是hook
?—— 本质是一个函数,把setup
函数中使用的Composition API
进行了封装,类似于vue2.x
中的mixin
。
自定义hook
的优势:复用代码, 让setup
中的逻辑更清楚易懂。
示例代码:
useSum.ts
中内容如下:
import {ref,onMounted} from 'vue'
export default function(){
let sum = ref(0)
const increment = ()=>{
sum.value += 1
}
const decrement = ()=>{
sum.value -= 1
}
onMounted(()=>{
increment()
})
//向外部暴露数据
return {sum,increment,decrement}
}
useDog.ts
中内容如下:
import {reactive,onMounted} from 'vue'
import axios,{AxiosError} from 'axios'
export default function(){
let dogList = reactive([])
// 方法
async function getDog(){
try {
// 发请求
let {data} = await axios.get('https://dog.ceo/api/breed/pembroke/images/random')
// 维护数据
dogList.push(data.message)
} catch (error) {
// 处理错误
const err = error
console.log(err.message)
}
}
// 挂载钩子
onMounted(()=>{
getDog()
})
//向外部暴露数据
return {dogList,getDog}
}
- 组件中具体使用:
当前求和为:{{sum}}
加载中......
本文由mdnice多平台发布