组合 API(Composition API)
初始组合 API
传统 option 配置方法写组件的时候,随着业务复杂度越来越高,代码量会越来越大,由于相关业务的代码需要组训 option 的配置,写在 data、methods 等位置,后续维护复杂,代码可复用性不高,使用组合 API 就能很好的规避这些问题,组合 API 的好处:代码都在 setup()里面,更加灵活,不受条条框框约束,增加代码可复用性
问题笔记
- setup()在创建组件之前就已经调用,顺序在 beforeCreate()前面,也就是说在 setup 里面没有 this,setup 里没有对象关系,不能使用 this
- import 必须包在 script 里面
- ref、reactive 都是方法,参数放到括号里,如:
const data = reactive({ count:66})
- setup 里的方法里调用参数,不使用 this,直接调用即可
- 声明的数据跟函数别忘了在 return 里面返回
- reactive 里面使用 computed,调用本 data 里的数据时,也需要写成 data.count 的样式
- computed 里面是一个匿名函数
- 导入子组件流程:
- import 引入子组件文件\
- 在父组件中 components 中声明该子组件
- 在父组件标签中插入使用
- setup()参数
- 第一个参数:props,这个参数在 setup 里面是只读的,如果转成响应式的可以百度一下,挺复杂麻烦的,而且基本也用不上
- 第二个参数:context,里面会存放没有在 props 中声明的其他传过来的属性,如:slots,parent,root,emit,refs 等
- context 也可以直接在形参处直接解构赋值,把对应的参数传进去
- setup()里面常规声明的变量是一个原生变量,不是响应式的,无法直接进行操作
常用 API
使用 API 之前,一定要先将对应的 API 引入
- ref
- 可以将单个变量变成响应式
let num = ref(6)
- 在方法中使用时,需要注意该变量在 return 后,在 div 中可以直接用
{{num}}
的形式使用,但是在 setup 中,如方法中使用时,它是一个 RefImpl 对象的形式,其中值在 value 里面,因此方法中使用时,num.value
才是其正确的值
- 可以将单个变量变成响应式
- reactive、toRefs
- reactive 只能声明一个对象,通常可以起名为 data(与 export default 中的 data 类似)
- reactive 里面值的使用方法就跟对象一样
- 如果想在 div 中直接拿到对象里的所有值,可以将其在 return 的时候以展开方法的方式进行展开,但是需要注意,如果直接展开,那数据就会失去响应式
- 如果想展开的数据也是响应式,可以配合 toRefs 使用,toRefs 可以将 return 展开的数组恢复成响应式,如
...toRefs(data)
- ref 中的数据也可以挂在到 reactive 中,但是一般没啥用,可以直接使用 reactive
- readonly 将声明一个变量将响应式的变量转为非响应式,如下,num 是响应式的变量,num2 就是非响应式的,只有操作 num 的时候值才会变化且 num2 的值会跟着一起变化,操作 num2 的时候,值是不会变化的
let num = ref(66);
let num2 = readonly(num);
- isRef 结合三元运算符使用,用作判断一个变量是否是响应式,如果是则给出一个输出,如果不是则给出另一个输出,类似的还有 isReadonly,isProxy 等等
计算属性 API computed
- computed()用来创建计算属性,返回值是一个 ref 的实例
- computed()里如果只有一个匿名函数,默认是 get 方法,如果需要添加 set 方法,则里面是一个对象
监听器 watch() watchEffect()
- watchEffect 是默认在组件加载的时候就会调用一次(可以通过配置更改执行时机),后面依赖属性发生了变更会继续执行
- watch 可以在使用时明确指定需要监听的属性,watchEffect 则是依赖回调函数中使用到的属性
- watch 指定监听的属性时,需要往 watch 里面传参,而不是传到内部的匿名函数中
- watch 内部的匿名函数可以接收两个参数,第一个是监听值的新值,第二个是监听值的旧值
- watch 监听的属性如果有多个,可以以数组的形式批量传入(匿名函数中新旧值也是一样)
- watch 默认需要监听的属性发生变更了才会执行,也就是如果监听的属性没有发生变更,默认不会执行,如果想让其在加载的时候先执行一次可以在 watch 的参数最后面加上一个
{immediate.true}
- watch 指定监听的属性传参时,可以传入 ref、reactive 类型监听整个对象,如果要监听对象里的某个值需要用一个匿名函数把对象里需要监听的值返回出来使用,监听里面多个值的时候就是一个匿名函数的数组
生命周期
- 声明周期引入的时候前面都会带一个 on
- 由于在 beforeCreate 跟 created 之前 setup 就已经创建了,因此 setup 里面没有这两个声明周期,setup 可以直接替代这两个声明周期
provide 与 inject
- provide 与 inject 在单独使用的时候,需要爷组件在 data 里也声明一个变量,然后把变量放到 provide 里面传给孙组件,不然只用 provide 传给孙组件,爷组件是不能用这个变量的,爷组件的数据跟孙组件的数据不是响应式的
- 在 setup 里面 provide 与 inject 是响应式的
router 与 vuex
- route 跟 router 是从 vue-router 里面引入的
- 引入的两个分别是 useRoute 和 useRouter 两个方法
- vuex 是从 vuex 里引入的,但是引入的是 useStore 状态管理对象的方法
- 引入以后赋值给一个变量,就可以正常的把变量当做 route、 router、store 使用了
- 使用状态管理里面的数据的时候,可以把 store 返回,也可以用$store 直接使用