Vantagens e características do framework Vue3
- Primeira renderização mais rápida
- O algoritmo diff é mais rápido
- menos pegada de memória
- Tamanho menor do pacote
- Melhor suporte para Typescript
Composition API
API de composição
1. Ciclo de vida
Para o ciclo de vida, não há muita mudança no geral, mas o nome da maioria dos ganchos de ciclo de vida é + “on”
, e as funções são semelhantes. Mas uma coisa a observar é que o Vue3 está em 组合式API
(API de composição, expanda abaixo) 使用生命周期钩子时需要先引入
, enquanto o Vue2 选项API
pode chamar ganchos de ciclo de vida diretamente em (API de opções), conforme mostrado abaixo.
view2 | ver 3 | ilustrar |
---|---|---|
antes de criar | configurar | Antes de criar o componente, execute as tarefas de inicialização |
criada | configurar | Depois que o componente é criado, acesse os dados e obtenha os dados da interface |
antes de montar | antes de montar | Antes do componente ser montado |
montado | onMounted | A montagem do componente está concluída, o DOM foi criado, acesse dados ou elementos DOM, acesse subcomponentes |
antes de atualizar | onBeforeUpdate | Não atualizado, obtenha todos os status antes da atualização |
Atualizada | onAtualizado | A montagem do componente está concluída, o DOM foi criado, acesse dados ou elementos DOM, acesse subcomponentes |
antes de destruir | onBeforeUnmount | Não atualizado, obtenha todos os status antes da atualização |
destruído | onUnmounted | Depois que o componente é destruído |
Tips: setup 是围绕 beforeCreate 和 created 生命周期钩子运行的,所以不需要显式地去定义。
2. API de composição
Vue2 é uma API de opções (Options API), uma lógica ficará espalhada em diferentes posições do arquivo ( data、props、computed、watch、生命周期钩子等
), resultando em baixa legibilidade do código. Quando você precisa modificar uma determinada lógica, precisa pular para cima e para baixo até o local do arquivo.
A API combinada Vue3 (API de composição) resolve esse problema muito bem. Ela pode escrever o conteúdo da mesma lógica em conjunto, o que melhora a legibilidade e a coesão do código e também fornece um plano de reutilização de lógica relativamente perfeito. Toda lógica está na setup
função, use ref、watch
funções como para organizar o código
Três, função de configuração
A função de configuração é a função de entrada da API combinada. Por padrão, as opções de configuração são exportadas, a função de configuração é declarada e os dados e funções são necessários para retornar o modelo.
setup
函数是Vue3
特有的选项,作为组合式API的起点- 从组件生命周期看,它在
beforeCreate
之前执行 - 函数中
this
不是组件实例,是undefined
- 如果数据或者函数在模板中使用,需要在
setup
返回 - 今后在vue3的项目中几乎用不到
this
, 所有的东西通过函数获取。
四、响应式原理
1. 原理
Vue2 响应式原理是利用es5的 Object.defineProperty()
对数据进行劫持结合发布订阅模式
来实现
Vue3 响应式原理是利用es6的 proxy
对数据代理,通过reactive()
函数给每一个对象都包一层 proxy
,通过 proxy 监听属性的变化,从而实现对数据的监控
2. Object.defineProperty的缺陷
对象新增、删除属性没有响应式
,数组新增、删除元素没有响应式;通过下标修改某个元素没有响应式;通过.length改变数组长度没有响应式
。只有实例创建时 data 中有的数据实例创建后才是响应式的,给已创建好的 vue 实例 data 对象中添加属性时,数据虽然会更新,但视图不会更新,不具有响应式
3.proxy的优势
-
proxy性能整体上优于Object.defineProperty
-
vue3支持更多数据类型的劫持
(vue2只支持Object、Array;vue3支持Object、Array、Map、WeakMap、Set、WeakSet) -
vue3支持更多时机来进行依赖收集和触发通知
(vue2只在get时进行依赖收集,vue3在get/has/iterate时进行依赖收集;vue2只在set时触发通知,vue3在set/add/delete/clear时触发通知),所以vue2中的响应式缺陷vue3可以实现
-
vue3做到了“精准数据”的数据劫持
(vue2会把整个data进行递归数据劫持,而vue3只有在用到某个对象时,才进行数据劫持,所以响应式更快并且占内存更小) -
vue3的依赖收集器更容易维护
(vue3监听和操作的是原生数组;vue2是通过重写的方法实现对数组的监控)
五、reactive函数和ref函数
reactive函数
通常使用它复杂类型的响应式数据
使用步骤
- 从
vue
中导入reactive
函数 - 在
setup
函数中,使用reactive
函数,传入一个普通对象,返回一个响应式数据对象 - 最后
setup
函数返回一个对象,包含该响应式对象即可,模板中可使用
ref函数
使用它定义响应式数据,不限类型
使用步骤
- 从
vue
中导入ref
函数 - 在
setup
函数中,使用ref
函数,传入普通数据(简单or复杂),返回一个响应式数据 - 最后
setup
函数返回一个对象,包含该响应式数据即可 - 注意:使用
ref
创建的数据,js
中需要.value
,template
中可省略
如何选择
reactive
可以转换对象成为响应式数据对象,但是不支持简单数据类型。ref
可以转换简单数据类型为响应式数据对象,也支持复杂数据类型,但是操作的时候需要.value
。- 它们各有特点,现在也没有最佳实践,没有明显的界限,所有大家可以自由选择。
- 如果能确定数据是对象且字段名称也确定,可使用
reactive
转成响应式数据,其他一概使用ref
。 - 在定义响应式数据的函数选择上,遵循:尽量使用
ref
函数支持所有场景,确定字段的对象使用reactive
可以省去.value
。
六、hooks
前言
hook: 直译[hʊk] 钩子
Hooks在前端领域并没有明确定义,借用知乎大佬的定义:在JS里是callback,事件驱动,集成定义一些可复用的方法。
官方对自定义hook定义:在 Vue 应用的概念中,“组合式函数” (Composables) 是一个利用 Vue 组合式 API 来封装和复用有状态逻辑的函数。
Vue3自定义Hooks
一些可复用的方法像钩子一样挂着,可以随时被引入和调用以实现高内聚低耦合的目标,应该都能算是hook;
hooks的作用
以函数形式抽离一些可复用的方法像钩子一样挂着,随时可以引入和调用,实现高内聚低耦合的目标;
-
将可复用功能抽离为外部JS文件
-
函数名/文件名以
use
开头,形如:useXX -
引用时将响应式变量或者方法显式解构暴露出来如:
const {nameRef,Fn} = useXX()
(在setup函数解构出自定义hooks的变量和方法)
Vue3自定义Hooks和Vue2时代Mixin的关系
Mixin/Class的局限性
在以往VUE2的选项式API中,主要通过Mixin或是Class继承来实现逻辑复用,但这种方式有三个明显的短板
:
- 不清晰的数据来源:当使用了多个mixin/class时,哪个数据是哪个模块提供的将变得难以追寻,这将提高维护难度
- 命名空间冲突:来自多个class/mixin的开发者可能会注册同样的属性名,造成冲突
- 隐性的跨模块交流:不同的mixin/class之间可能存在某种相互作用,产生未知的后果
Hooks的优势
其实Mixin/Class的缺点反过来就是Hooks的优点:
- 清晰一目了然的源头:Hooks不是一个类,没有将状态、方法存放在对象中,然后通过导出对象的形式实现复用,也就不会有对象间过度
耦合
、干扰
等问题。Hooks中的各类状态是封装在内部的,与外界隔离,仅暴露部分函数、变量,这使得其来源、功能清晰可辨
且不易被干扰
- 没有命名冲突的问题:Hooks本质是闭包函数,内部所导出的变量、方法支持重命名,因而同一个Hook在同一个组件中可以N次使用而不冲突
- 精简逻辑:一个Hook开发完成后,在使用Hook时不需要关心其内部逻辑,只需知道有什么效果、如何使用即可,专注于其他核心业务逻辑,可以节省大量重复代码
Hooks的各类规范
- Hook的命名需要以
use
开头,比如useTimeOut,这是约定俗成的,开发者看到useXXX即可明白这是一个Hook。Hook的名称需要清楚地表明其功能。 - 只在当前关注的最顶级作用域使用Hook,而不要在嵌套函数、循环中调用Hook
- 函数必须是纯函数,没有副作用
- 返回值是一个函数或数据,供外部使用
- Hook内部可以使用其他的Hook,组合功能
- 数据必须依赖于输入,不依赖于外部状态,保持数据流的明确性
- 在Hook内部处理错误,不要把错误抛出到外部,否则会增加hook的使用成本
- Hook是单一功能的,不要给一个Hook设计过多功能。
如何创建自己的自定义Hook
在设计一个定制的Hook之前,应当至少明白以下几点:
- 明确自己想要的功能以及实现的效果
- 遵守Hook的命名规范以及其他注意事项
- 尽可能好的性能表现以及精简的代码
- 使用TypeScript