Vue 学习笔记12:Vue3常用组合API

Vue 学习笔记11:Vue3组合API

  • 一、创建 Vue3 工程
    • 1. 使用 vue-cli 创建
    • 2. 使用 vite 创建
    • 3. 安装 vue3 插件
  • 二、常用 composition API
    • 1. setup 函数
    • 2. ref 函数
    • 3. reactive 函数
    • 4. Vue3 的响应式
    • 5. reactive 对比 ref
    • 6. setup 的两个注意点
    • 7. 计算属性与监视
      • (1)computed 函数
      • (2)watch 函数
      • (3)watchEffect 函数
    • 8. Vue3 生命周期
    • 9. 自定义 hook 函数
    • 10. toRef

一、创建 Vue3 工程

1. 使用 vue-cli 创建

  • 查看 vue-cli 版本,确保在 4.5.0 以上 vue -V
  • 如果版本没有高于 4.5.0 就重新安装 vue-cli
    Vue 学习笔记12:Vue3常用组合API_第1张图片

2. 使用 vite 创建

## 创建工程
npm init vite-app 工程名称
## 进入工程目录
cd 工程名称
## 安装依赖
npm i
## 运行
npm run dev

Vue 学习笔记12:Vue3常用组合API_第2张图片

3. 安装 vue3 插件

点击第一个,添加到 Chrome
Vue 学习笔记12:Vue3常用组合API_第3张图片
Vue 学习笔记12:Vue3常用组合API_第4张图片

二、常用 composition API

1. setup 函数

  • setup 是所有 Composition API(组合API)“表演的舞台”
  • 组件中所用到的:数据、方法等等,均要配置在 setup 中
  • setup 函数的两种返回值:
  1. 若返回一个对象,则对象中的属性、方法,在模板中均可直接使用(常用)
    Vue 学习笔记12:Vue3常用组合API_第5张图片
  2. 若返回一个渲染函数,则可以自定义渲染内容。
  • 注意点:
  1. 尽量不要与 Vue2 配置混用
  2. setup 不能是一个 async 函数

2. ref 函数

  • 作用:定义一个响应式的数据。
  • 语法:const xxx = ref(initvalue)
  1. 创建一个包含响应式数据的【引用对象】(reference对象,简称ref对象)
  2. JS 中操作数据:xxx.value
  3. 模板中读取数据:
    {{xxx}}
  • 备注:
  1. 接收的数据可以是:基本类型,也可以是对象类型。
  2. 基本类型的数据:响应式依然是依靠 Object.defineProperty()getset
  3. 对象类型的数据:内部求助了 Vue3 中的一个新函数 reactive()
    Vue 学习笔记12:Vue3常用组合API_第6张图片

3. reactive 函数

  • 作用:定义一个【对象类型】的响应式数据(基本类型不要用它,要用 ref 函数)
  • 语法:const 代理对象 = reactive(源对象) 接收一个对象(或数组),返回一个代理对象(Proxy 的实例对象,简称 Proxy 对象)
  • reactive 定义的响应式数据是“深层次的”
  • 内部给予 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据进行操作。
    Vue 学习笔记12:Vue3常用组合API_第7张图片

4. Vue3 的响应式

  • 通过 Proxy(代理):拦截对象中任意属性的变化,包括属性值的读写、添加、删除。Object.defineProperty() 只能拦截读写。
  • 通过 Reflect(反射):对源对象的属性进行操作,返回布尔值,代表是否操作成功。
new Proxy(data, {
	// 拦截读取属性值
	get(target, prop){
		return Reflect.get(target, prop)	
	},
	// 拦截设置属性值或添加新属性
	set(target, prop){
		return Reflect.set(target, prop, value)
	}
	// 拦截删除属性
	deleteProperty(target, prop){
		return Reflect.deleteProperty(target, prop)
	}
})

5. reactive 对比 ref

  • 从定义数据角度对比:

ref 用来定义:【基本类型数据】
reactive 用来定义:【对象或数组类型数据】
备注:ref 也可以用来定义对象或数组类型数据,它内部会自动通过 reactive 转为代理对象

  • 从原理角度对比:

ref 通过 Object.defineProperty() 的 get 与 set 来实现响应式(数据劫持)。
reactive 通过使用 Proxy 来实现响应式,并通过 Reflect 操作源对象内部的数据。

  • 从使用角度对比:

ref 定义的数据:操作数据需要 .value,读取数据时模板中直接读取不需要 .value
reactive 定义的数据:操作数据与读取数据,均不需要 .value

6. setup 的两个注意点

  • setup 执行的时机:在 beforeCreate 之前执行一次,this 是 undefined。
  • setup 的参数
  1. props:值为对象,包含:组件外部传递过来,且组件内部声明接受了的属性。

  2. context:上下文对象

    attrs:值为对象,包含:组件外部传递过来,但没有在 props 配置中声明的属性,相当于 this.$attrs
    slots:收到的插槽内容,相当于 this.$slots
    emit:分发自定义事件的函数,相当于 this.$emit

7. 计算属性与监视

(1)computed 函数

  • 与 Vue2 中的 computed 配置功能一样
  • 写法
import { computed } from 'vue'

setup(){
	...
	// 计算属性——简写(没有考虑计算属性被修改的情况)
	let fullName = computed(() => {
		return person.firstName + '-' + person.lastName	
	})

	// 计算属性——完整
	let fullName = computed({
		get(){
			return person.firstName + '-' + person.lastName	
		},
		set(value){
			const nameArr = value.split("-")
			person.firstName = nameArr[0]
			person.lastName = nameArr[1]	
		}	
	})

(2)watch 函数

  • 与 Vue2 中的 watch 配置功能一致

  • 两个小坑:

    监视 reactive 定义的响应式数据时:oldValue 无法正确获取、强制开启了深度监视(deep 配置失效)
    监视 reactive 定义的响应式数据中某个属性时:deep 配置有效。

// 情况一:监视【一个】 ref 定义的响应式数据
watch(sum, (newValue, oldValue) => {
	console.log('sum变化了', newValue, oldValue)	
}, {immediate: true})

// 情况二:监视【多个】 ref 定义的响应式数据
watch([sum, msg], (newValue, oldValue) => {
	console.log('sum 和 msg 变化了', newValue, oldValue)	
})

// 情况三:监视 reactive 定义的响应式数据,无法正确获得 oldValue,强制开启深度监视
watch(person, (newValue, oldValue) => {
	console.log('person 变化了', newValue, oldValue)	
}.{immediate: true, deep: false})  // 此处的 deep 配置失效

// 情况四:监视 reactive 定义的响应式数据中的【某个】属性
watch(() => person.job, (newValue, oldValue) => {
	console.log('person的job变化了', newValue, oldValue)	
}.{immediate: true, deep: true})  // 此处的 deep 配置奏效

// 情况五:监视 reactive 定义的响应式数据中的【某些】属性
watch([() => person.name, () => person.age], (newValue, oldValue) => {
	console.log('person的name或age变化了', newValue, oldValue)	
})

(3)watchEffect 函数

  • watch 的套路是:既要指明监视的属性,也要指明监视的回调。
  • watchEffect 的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。
  • watchEffect 有点像 computed:

    但 computed 注重的计算出来的值(回调函数的返回值),所以必须要写返回值。
    而 watchEffect 更注重的是过程(回调函数的函数体),所以不用写返回值。

// watchEffect 所指定的回调中用到的数据只要发生变化,则直接重新执行回调
watchEffect(() => {
	const x1 = sum.value
	const x2 = person.name
	console.log("watchEffect配置的回调执行了")
})

8. Vue3 生命周期

Vue 学习笔记12:Vue3常用组合API_第8张图片
新的生命周期钩子

  • Vue3 中可以继续使用 Vue2 中的生命周期钩子,但有两个被更名:

    beforeDestory 改名为 beforeUnmounted
    destory 改名为 unmounted

  • Vue3 也提供了 Composition API 形式的生命周期钩子,与 Vue2 中的钩子对应如下:

    beforeCreate ===> setup()
    create ===> setup()
    beforeMount ===> onBeforeMount
    mounted ===> onMounted
    beforeUpdate ===> onBeforeUpdate
    updated ===> onUpdate
    beforeUnmount ===> onBeforeUnmount
    unmounted ===> onUnmounted

  • Vue2 中的 beforeCreatecreate 不能写进 setup 中

  • setup 中的钩子比 Vue2 中的钩子优先级高

9. 自定义 hook 函数

  • 什么是 hook?——本质是一个函数,把 setup 函数中使用的 Composition API 进行封装。
  • 类似于 Vue2 中的 mixin
  • 自定义 hook的优势:代码复用,让 setup 中的逻辑更清楚易懂。

10. toRef

  • 作用:创建一个 ref 对象,其 value 值指向另一个对象中的某个属性
  • 语法:const name = toRef(person, 'name')
  • 应用:要将响应式对象中的某个属性单独提供给外部使用时。
  • 扩展:toRefstoRef 功能一致,但可以批量创建多个 ref 对象,语法:toRefs(person)

你可能感兴趣的:(前端,javascript,前端,js,vue.js,vue)