vueMastery观后感
vue2的几个痛点
随着组件增长,组件会越来越大,越来越丑,因此可读性和可维护性变差
options API1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<script>
export default{
data(){
return {
searchData:'',
sortingData:'',
}
},
methods:{
searchFn(){
},
sortingFn(){
}
}
}
</script>composition API
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<script>
export default{
setup(){
return {...useSearch(),...useSorting()}
}
}
function useSearch(){
}
function useSorting(){
}
</script>对比两种方式的区别,当组件越来越大,options API 写起来如同琦玉的认真往返跳
跨多个组件重用代码片段时,所有重用方法都有缺陷
- mixins:会导致属性名冲突,也不清楚这些mixins如何交互,而且还是不能够灵活对应功能进行重用
- mixins工厂:更加复杂,需要命名空间这种强大的规则和约束,并且仍然需要查看每个mixin的内部暴露了哪些属性
- 插槽:降低可读性,不够灵活
- 高阶组件:从没用过,听说就不是人用的东西
Vue3 提供了composition Functions
use/search.jsuse/sorting.js1
2
3export default function useSearch(getResults){
...
}search.vue1
2
3export default function useSorting({input, options}){
...
}唯一的缺点是,现在有两种不同的语法用于定义组件1
2
3
4
5
6
7
8
9
10
11import useSearch from '@/use/search'
import useSorting from '@/use/sorting'
export default {
setup (){
const productSearch = useSearch()
const resultSorting = useSorting({})
return {productSearch, resultSorting}
}
}
mixin是原来最常用的,这是一种交叉继承,说白了就是一个儿子有俩爹,一个爹教你会飞,一个爹教你会游,但是传宗接代后你不知这个技能来自谁,数据和方法不知道是从哪来的
尤大:coposition API吊打mixin
对Typescript支持有限
composition API 的基本姿势
setup和ref
setup没有this,setup是在beforeCreate和created之间执行
setup其实可以理解为做初始化,肯定是最早执行
ref多数使用场景是基本类型,何为响应式对象,必须要是对象,所以需要ref包装一下
composition API中methods基本用法
setup中想改变ref定义的响应式对象,需要用这个对象的value属性,模板上引用则不需要
composition API中computed基本用法
1 | <script> |
computed返回值是一个readOnly的泛型ref,不能直接改,不然会报错,想改的话必须用get,set用法
如果computed放在reactive中使用,等于对ref进行了拆箱操作,则不需要后面跟value
composition API中reactive响应式语法
1 | <script> |
何时用ref,何时用reactive?
理论上reactive更常用些,ref作用在于拆分,可以用于业务符合,或者就单个值,直接用ref就完了
isRef能判断一个变量是不是ref,unRef可以对ref进行拆箱
< script setup >语法糖有的话,就不用考虑这些事了
composition Function模块化
1 | <script> |
也可以从不同文件引入
use/event-space.js
1 | import {reactive, computed, toRefs} from "vue"; |
可以引用多个文件
1 | import useEventSpace from "@/use/event-space" |
但是这样会导致不能清晰看出哪些方法来自哪个composition function,可以用解构赋值的写法写
1 | import useEventSpace from "@/use/event-space" |
setup理应很清爽,就是各种功能模块调用
可复用的话,直接放到use文件夹下的JS文件内,不可复用直接拿到setup外,说白了只是在写js,不是在写vue(有hooks那味了,useState)
这样确实利于维护,但是跟hooks用法一样,但是底层实现完全不一样
为什么可以解决vuex的持久化?
lifecycle hooks生命周期钩子
生命周期钩子变动
beforeDestroy () -> beforeUnmount()
destroyed() -> unmounted()
在setup中使用生命周期钩子,只需要在钩子前增加”on”
1 | import { onBeforeMount, onMounted } from "vue" |
其中缺少了beforeCreated和created,因为实际周期是setup在beforeCreated和created之间调用,也可以理解为放在setup中的代码,就是放在beforeCreated和created中
现在多了两个生命周期钩子:
- onRenderTracked: render function第一次访问响应式依赖时调用,一般调试时用于查看哪些依赖项在被追踪,
- onRenderTriggered: 触发新渲染时调用,一般调试时用于查看哪些依赖项触发了组件的重新渲染
setup函数中的生命周期钩子,例如onMounted,其实只是将onMounted传进去的这个函数保存在onMounted数组里,当mounted这个钩子真的触发时,就把数组里的函数都执行一遍,所以setup函数中有多个相同的生命周期钩子则会叠加,并不会替换(发布订阅模式,一个一个订阅,统一发布)
数据侦听watch
加入了一个新api,watchEffect
1 | import { ref, watchEffect } from "vue" |
watchEffect会立即执行,参数函数中有响应式对象改变时,将会重新运行
当然watch还是可以用的
1 | watch(searchInput,(newVal,oldVal) => { |
这里如果watch一个ref,那么直接这样写就行了,如果watch一个reactive对象其中的一个值,那要以回调参数的返回值来写?(存在疑问)
当然还可以监听多个参数
1 | watch([firstName,LastName],([newFirst,newFirst],([oldFirst,oldFirst]) => { |
别忘了watch还有immediate选项
1 | watch(searchInput,(newVal,oldVal) => { |
共享状态 sharing state
B站资源 :
https://www.bilibili.com/video/BV12k4y1y75T?from=search&seid=165729587306922938