• Vue.js实现浅析_前端培训


    实现浅析 

    vue-hooks  的源码目前只有不到 200 行, 非常简明扼要的实现了以上提到的 Hooks 和方法等。

    首先大体看一下:

    let currentInstance = nulllet isMounting = falselet callIndex = 0 //… export function useState(initial) {  //…}export function useEffect(rawEffect, deps) {  //…}export function useRef(initial) {  //…}export function useData(initial) {  //…}export function useMounted(fn) {  //…}export function useDestroyed(fn) {  //…}export function useUpdated(fn, deps) {  //…}export function useWatch(getter, cb, options) {  //…}export function useComputed(getter) {  //…} export function withHooks(render) {  return {    data() {      return {        _state: {}      }    },    created() {      this._effectStore = {}      this._refsStore = {}      this._computedStore = {}    },    render(h) {      callIndex = 0      currentInstance = this      isMounting = !this._vnode      const ret = render(h, this.$props)      currentInstance = null      return ret    }  }} //暴漏的钩子函数export function hooks (Vue) {  Vue.mixin({    beforeCreate() {      const { hooks, data } = this.$options      if (hooks) {        this._effectStore = {}        this._refsStore = {}        this._computedStore = {}        this.$options.data = function () {          const ret = data ? data.call(this) : {}          ret._state = {}          return ret        }      }    },    beforeMount() {      const { hooks, render } = this.$options      if (hooks && render) {        this.$options.render = function(h) {          callIndex = 0          currentInstance = this          isMounting = !this._vnode          const hookProps = hooks(this.$props)          Object.assign(this._self, hookProps)          const ret = render.call(this, h)          currentInstance = null          return ret        }      }    }  })}

    基本的结构非常清楚,可以看出:

    withHooks  返回一个包装过的 Vue 实例配置

    hooks  以 mixin 的形式发挥作用,注入两个生命周期

    用模块局部变量 currentInstance 记录了 Hooks 生效的 Vue 实例

    其次值得注意的是处理副作用的 useEffect

    export function useEffect(rawEffect, deps) {  //…  if (isMounting) {    const cleanup = () => {      const { current } = cleanup      if (current) {        current()        cleanup.current = null      }    }    const effect = () => {      const { current } = effect      if (current) {        cleanup.current = current()        effect.current = null      }    }    effect.current = rawEffect     currentInstance._effectStore[id] = {      effect,      cleanup,      deps    }     currentInstance.$on(‘hook:mounted’, effect)    currentInstance.$on(‘hook:destroyed’, cleanup)    if (!deps || deps.lenght > 0) {      currentInstance.$on(‘hook:updated’, effect)    }  } else {    const record = currentInstance._effectStore[id]    const { effect, cleanup, deps: prevDeps = [] } = record    record.deps = deps    if (!deps || deps.some((d, i) => d !== prevDeps[i])) {      cleanup()      effect.current = rawEffect    }  }}

    其核心大致轨迹如下:

    声明 effect 函数和 cleanup 函数

    将调用 Hook 时传入的 rawEffect 赋值到 effect.current 属性上

    effect() 运行后,将 rawEffect 运行后的返回值赋值到 cleanup.current 上

    在 Vue 本身就支持的几个 hook:xxx  生命周期钩子事件中,调用 effect 或 cleanup

    这样再去看这两个 Hook 就敞亮多了:

    另外常用的 useData  也是利用了 Vue 实例的 $set  方法,清晰易懂:

    同样利用实例方法的: 

    其余几个 Hooks 的实现大同小异,就不逐一展开说明了。

    IV. 总结

    React Hook 是简化组件定义、复用状态逻辑的一种最新尝试

    vue-hooks 很好的实现了相同的功能,并且结合 Vue 实例的特点提供了适用的 Hooks。

  • 相关阅读:
    这个户型设计前端图形化技术,你可能一辈子也学不会!
    掌上道聚城 评论区的复制按钮怎么实现
    freeRTOS学习(一)
    【Linux学习】基础开发工具
    gradle 使用 ext
    【漏洞复现】SpringBlade dict-biz SQL注入漏洞
    Ubuntu Nginx 配置 SSL 证书
    Spring Boot中捕获异常错误信息并将其保存到数据库中
    HTML5+JavaScript绘制彩虹和云朵
    Webpack--动态 import 原理及源码分析
  • 原文地址:https://blog.csdn.net/zjjcchina/article/details/126521531