Composition API
又名组合式api
vue3.x的生命周期分为 options API(选项式api) 和 Composition API(组合式api) , options API和vue2.x的生命周期差不多,但beforeDestory改成了beforeUnmount, destory改为unmounted,其他保持一致
Composition API
setup()函数相当于created和beforeCreate的集合,其他生命周期的钩子都应该在这个函数里面进行,setup函数返回的数据可以直接在模版中使用,不需要通过.value的方式,因为组件都帮我们处理好了(前提是响应式数据)
其他生命周期:import { onBeforeMounted , onMounted , onBeforeUpdate , onUpdate , onBeforeUnmounted , onMounted } from vue;
这些生命周期钩子只能用在setup函数中,因为他们依赖于内部的全局状态来定位当前的活动的实例,
理解Composition API中的ref 、 refs 、 toRefs
ref:生成值类型的响应式数据、可用于模版和reactive(响应式对象)、通过.value修改值
import {ref , reactive} from vue;
export default {
name:'Ref',
setup(){
const ageRef = ref(20);
const nameRef = ref('雨枫');
const state = reactive({
name:nameRef
})
setTimeOut(()=>{
ageRef.value = 30;
nameRef.value = '雨枫111';
},1000)
return {
ageRef,
state
}
}
}
toRef:针对一个响应式对象,对里面的某个property创建一个ref,具有响应式,两者保持引用关系
const state = reactive({
foo: 1,
bar: 2
})
const fooRef = toRef(state, 'foo')
fooRef.value++
console.log(state.foo)
state.foo++
console.log(fooRef.value)
注意:toRef如果用于普通对象,产出的结果不具备响应式
toRefs:将响应式对象转化为普通对象,对象的每一个property都是对应的一个ref,两者保持引用关系
const state = reactive({
foo: 1,
bar: 2
})
const stateAsRefs = toRefs(state)
state.foo++
console.log(stateAsRefs.foo.value)
stateAsRefs.foo.value++
console.log(state.foo)
最佳实践总结:
* 用reactive 做响应式对象
用ref做值类型的响应式
setup中返回toRefs(state),或者toref(state,'xxx')
ref的变量命名都有xxxRef
合成函数返回响应式对象,使用toRefs*
在较大的应用中建议选择使用 Composition Api,可以实现逻辑复用
Composition Api抽离逻辑代码到一个函数
函数命名约定为 useXXX 格式
在setup中使用useXXX函数
React Hooks
react 16.8版本出来的,100%的向后兼容,没有破坏性改动,不会取代class组件,只能应用于函数组件
什么是hook:
他是让你在函数组件里‘钩入’ react state 和生命周期等特性的函数
函数组件特点:
没有组件实例
没有生命周期
没有state 和 setState,只能接收props,然后返回一个jsx
函数组件是一个纯函数,无法存储一个state,执行完即销毁
class组件的问题:
大型组件很难拆分和重构
相同的业务逻辑分散到各个方法中,逻辑混乱
复用逻辑变得复杂,例如Mixins 、HOC 、 Render Prop
综上所述总结:
react组件更易用函数表达(react官网)
react提倡函数式编程
函数更灵活、更易拆分、更易测试
但是函数组件太简单、需要能力增强 ---- 衍生出 React Hooks
hooks命名规范:
所有hooks都以use开头,自定义hooks也需要use开头,非hooks的地方尽量不要用useXXX的写法
useState: 创建函数组件内部state的hook
import React, { useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useEffect 模拟组件的生命周期
模拟class组件DidMount 和 DidUpdate
useEffect(()=>{
console.log('ajax请求')
})
每次赋值都会执行effect
模拟class组件DidMount
useEffect(()=>{
console.log('初始化')
},[])
模拟class组件DidUpdate
useEffect(()=>{
console.log('更新')
},[count])
模拟 componentWillUnMount(组件销毁的生命周期)
useEffect(()=>{
return ()=>{
console.log('结束了')
}
},[])
注意:如果useEffect()函数不传第二个依赖数组的话,内部返回函数的时候每次都会执行清除操作,并不是完全和componentWillUnMount一样
小结:useEffect在组件渲染后会有不同的副作用,有些需要清除(比如:引起内容泄漏的定时器,页面绑定了的全局dom事件等),其他的effect也可以不用清除,内部不用返回函数
多个useEffect是按声明的顺序依次调用的
useRef:获取dom节点
useContext:给很多层下级组件传参
useReducer:是useState组件的替代方案,用于state复杂变化
useMemo:用来hooks的性能优化