组合式API - setup选项
组合式API可理解为一系列函数,通常需要调用这些函数去编写将来的组件逻辑;
而setup为组合式API的入口(只有先写了setup才能往里写组合式API的函数)
setup选项的写法及执行时机
执行时机在beforeCreate之前
效果展示:
this问题
创建实例之前去执行的,setup函数中获取不到this,this是undefined
setup选项中写代码的特点
setup函数中提供的所有数据/函数,如果想要在模板中应用,必须return
问题:每次都return太麻烦
使用<script setup>语法糖简化代码
组合式API - reactive和ref函数
问题:在vue中默认数据并非是响应式的;
如果我们希望数据是响应式的;需要借助reactive或者ref函数进行处理
reactive()
作用:接收对象类型的数据作为参数传入,并返回一个响应式的对象
步骤:
- 从vue包中导入reactive函数
import {reactive} from 'vue'
- 在<script setup>中执行reactive函数,并传入类型为对象的初始值,并使用变量接收返回值
ref()
作用:接收简单类型或对象类型的数据传入,并返回一个响应式的对象
步骤:
- 从vue包中导入ref函数
import {ref} from 'vue'
- 在<script setup>中执行ref函数并传入初始值,使用变量接收ref函数的返回值
得到一对象,对象里有一个value属性,属性值为0;所以访问数据的时候,需要通过.value
注意点:在script中访问数据需要通过.value;template中不需要加.value(帮我们扒了一层)
其本质是:在原有传入数据的基础上,外层包了一层对象,再借助reactive实现的响应式
效果展示:
升级 —— +1操作
组合式API - computed
computed计算属性函数
步骤:
- 导入computed函数
import { computed } from 'vue'
- 执行函数,用变量去接收;computed函数的回调参数为 计算属性的计算逻辑
const 计算属性 = computed( () => {
return 基于响应式数据做计算之后的值
})
案例
需求:基于[1,2,3,4,5,6,7,8] 筛选出所有数字大于2的 得到 [3,4,5,6,7,8]
filter函数
效果展示:
扩展 —— 实现对数组的修改
效果展示:
组合式API - watch
watch函数
作用:侦听一个或多个数据的变化,数据变化时执行回调函数
侦听单个数据
步骤:
- 导入watch函数
import {watch} from 'vue'
- 调用watch函数;传入要侦听的响应式数据(ref对象)和 回调函数
watch(ref对象,(newValue,oldValue) => {...})
newValue:变化后的 ;oldValue:变化前的
一旦这个ref对象变化了,就执行后面的回调函数
效果展示:
侦听多个数据
写成数组形式
watch([ref对象1,ref对象2],(newArr,oldArr) => {...})
一旦数组里任意一个发生了变化,都会触发后面的回调函数
效果展示:
配置项 —— immediate
立刻执行(一进页面就执行一次)—— 侦听器创建时就立即触发回调;
响应式数据变化之后,继续执行回调
步骤:
将 {immediate: true} 写在watch函数的第三个参数的位置
效果展示:
配置项 —— deep
深度监视
为什么要有deep:true,watch不是已经监视了吗
默认watch进行的是浅层监视, const 数据ref = ref(简单类型) 可以直接监视
但如果传的是复杂类型,就监视不到复杂类型内部数据的变化
这么写,拿不到;只有userInfo.value对象的地址变化了,才可以监视的到
像这样
效果展示:
想要userInfo.value对象的age++也能监视的到,就需要采用深度监视
效果展示:
精确侦听对象的某个属性
需求:只想侦听对象中的某一个属性的变化,而不需要侦听整个对象里面所有属性的变化
即只有某个特定属性变化时,才执行回调
就是说 name改李四,也会触发侦听;因为是深度触发
改age才触发
组合式API - 生命周期函数
区别于Vue2:销毁阶段的beforeDestory和destoryed 换成了beforeUnmount和unmounted
规则
选项式API,里面写在beforeCreate/created里面的代码,到了组合式API要写在setup里面
eg. created里面发的请求(到了created这个钩子,响应数据已经准备好了)
其余的,on开头
演示
组合式API - 父子通信
组合式API下的父传子
步骤:
- 父组件中给子组件绑定属性
- 子组件内部通过props选项接收
这里注意:有了setup之后,我们通过defineProps"编译宏" 接收子组件传递的数据
目标:父组件里面的数据将来要传递给子,并且在子里做渲染
Case1. 传的是写死的值
Case2. 传一个动态的值(响应式的数据)
效果展示:
响应式
老爹数据变化,儿子实时更新
效果展示:
组合式API下的子传父
步骤:
- 父组件中给子组件标签通过@绑定自定义事件,进行侦听
v-on:事件名 = "内联语句"
添加监听 + 提供处理逻辑
- 通过defineEmits"编译宏" 生成emit方法
defineEmits(['自定义事件名'])
emit要触发的事件,需要在上面的编译器宏中去声明
- 子组件内部通过emit方法触发事件
emit('自定义事件名',参数)
效果展示:
组合式API - 模板引用
通过ref标识去获取页面中真实的dom对象或组件实例对象;进而调到dom/组件里的属性或方法
语法:
- 调用ref函数,生成一个ref对象
- 通过ref标识,进行绑定
- 通过ref对象.value即可访问到绑定的元素(必须是渲染完之后才能拿得到;onMounted这个钩子处,模板就已经渲染好了)
案例:
获取dom
一进页面就聚焦
点击按钮聚焦
获取组件的属性/方法
注意:
vue3中,默认情况下在<script setup>语法糖下组件内部的属性和方法是不对外开放的;
如果想要在外部访问到,就需要通过defineExpose编译宏指定哪些属性和方法允许访问
效果展示:
组合式API - provide和inject
作用:顶层组件向任意的底层组件传递数据和方法,实现跨层组件通信
规则:
顶层组件通过provide函数提供数据
底层组件通过inject函数获取数据
分情况讨论:
Case1. 跨层传递普通数据
顶层组件:provide('key','value')
底层组件:const message = inject('key')
效果展示:
Case2. 跨层传递响应式数据
顶层组件:provide('key',ref对象)
底层组件:const message = inject('key')
效果展示:
Case3. 跨层传递函数
使用场景:底层想修改顶层的数据,但我们遵循的是谁的数据谁来维护;这时可以让顶层给子孙后代传递 可以修改数据的方法
效果展示:
vue3.3以上版本新特性 - defineOptions
问题:使用了<script setup> 语法糖,无法提供一些和setup平级的属性
—— Vue3.3以上版本引入 defineOptions 宏 ,可用来定义任意选项;
props、emits、expose除外,这些有专门对应的defineProps、defineEmits、defineExpose
在此之前,如果我们要定义组件的name或其他自定义属性,都是再添加一个普通的<script>标签,这样就会存在两个<script>标签
defineOptions 宏函数
vue3.3以上版本新特性 - defineModel
Vue3中的 v-model 相当于:modelValue(v-bind:属性名)和 @update:modelValue(v-on:事件名)
即传递一个modelValue属性,同时触发update:modelValue事件
案例:
实现父子组件的双向数据绑定
新版本改进
加配置