vue3 Composition API 和 React Hooks

328 阅读4分钟

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) // 2

    state.foo++
    console.log(fooRef.value) // 3

    注意:toRef如果用于普通对象,产出的结果不具备响应式
    
toRefs:将响应式对象转化为普通对象,对象的每一个property都是对应的一个ref,两者保持引用关系

    const state = reactive({
      foo: 1,
      bar: 2
    })

    const stateAsRefs = toRefs(state)
    /*
    stateAsRefs 的类型:

    {
      foo: Ref<number>,
      bar: Ref<number>
    }
    */

    // ref 和原始 property 已经“链接”起来了
    state.foo++
    console.log(stateAsRefs.foo.value) // 2

    stateAsRefs.foo.value++
    console.log(state.foo) // 3


最佳实践总结:
   * 用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() {
          // 声明一个叫 "count" 的 state 变量  
          const [count, setCount] = useState(0);
          return (
            <div>
              <p>You clicked {count} times</p>
              <button onClick={() => setCount(count + 1)}>
                Click me
              </button>
            </div>
          );
        }
        
        
   useEffect 模拟组件的生命周期
       模拟class组件DidMountDidUpdate
       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的性能优化