Vuex探讨第二站-为什么要在beforeCreate中代理store

因为对Vuex很感兴趣,而且工作中用到的技术栈也是它,所以停留在api调用工程师肯定不行,所以就去看了看源码,研究其中的实现内容。

如果有任何问题,还请各位大佬不吝赐教

主要背景

之前写过一篇文章:Vuex探讨第一站-小小重写。今天再进行回顾时。发现一个问题,主要是在install函数中

js 复制代码
function install(_Vue) {
    console.log('111');
    if (Vue && Vue === _Vue) {
        console.error('只能vue.use一次');
        return
    }
    Vue = _Vue
    _Vue.mixin({
        beforeCreate() {
            console.log('==>Get this.$options', this.$options);
            // 根组件存在store 
            if (this.$options && this.$options.store) {
                this.$store = this.$options.store
            } else {
                // 从父组件获取
                this.$store = this.$parent && this.$parent.$store
            }
        }
    })
}

为什么执行_Vue.mixin时,只能在beforeCreate生命周期钩子中吗,不能再created等其他生命周期中吗?。骤然一想,确实是我忽略了,带着这个问题,我假设了一个场景。

具体场景

vue 复制代码
<template>
  <div id="app">
    <div>
      {{ b }}
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      b: this.$store.state.b,
    };
  },
  mounted() {},
  methods: {
  },
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

如下,我在组件初始化中需要获取store中的值,key为b。那么我现在来进行调试。

第一步还是先beforeCreate,验证发现都可以正常获取值

紧接着我换成了created,不出意外的话,出了意外。直接报错了。

说白了,就是state属性没有。那么可以思考下,两个钩子之间难道做了什么操作导致了获取数据时,直接报错了,带着这个问题,我来看了vue的源码

vue相关代码

这是vue的部分代码,主要是初始化执行的,主要看这几步

js 复制代码
// 调用 beforeCreate 函数
callHook(vm, 'beforeCreate', undefined, false /* setContext */)
// 在data/props之前解析注入
initInjections(vm)
// 初始化data、props、computed等
initState(vm)
// 在data/props之后解析提供
initProvide(vm)
// 调用 created 函数
callHook(vm, 'created')

最主要的initState函数

js 复制代码
 const opts = vm.$options
  // 初始化props
  if (opts.props) initProps(vm, opts.props)

  // Composition API
  initSetup(vm)

  // 初始化methods
  if (opts.methods) initMethods(vm, opts.methods)
  // 初始化data
  if (opts.data) {
    initData(vm)
  } else {
    const ob = observe((vm._data = {}))
    ob && ob.vmCount++
  }
  // 初始化computed
  if (opts.computed) initComputed(vm, opts.computed)
  // 初始化watch
  if (opts.watch && opts.watch !== nativeWatch) {
    initWatch(vm, opts.watch)
  }

好好好,恍然大悟了,如果是在created中混入,组件的data都已经初始化了,在获取值的时候,state还没有,当然要报错了。哦哦哦,原来如此,也算又搞明白了一点。

总结

大牛们的设计都是有因有果的,不是贸然的,每天能学习到一个小点,也是不错的,有收获的。

相关推荐
java1234_小锋31 分钟前
【技术专题】HTML5 网页技术 - HTML5 Canvas 基础以及动画入门
前端·html·html5
知了学历孙老师4 小时前
小自考的校考和统考,出题方和难度差在哪
java·大数据·前端
ShineWinsu6 小时前
对于JavaScript:操作元素的解析
开发语言·前端·javascript·面试·web·dom·元素
福兮说6 小时前
JSON 格式正确,数据就可靠吗?我用一份自编配置检查类型与空值
java·前端·json
程序员老赵8 小时前
Docker 部署青龙面板:轻松搭建定时任务管理平台
前端·docker·开源
Swot8 小时前
Asciidoctor 公式数字下标错位问题:原因分析与解决方案
前端
Swot8 小时前
leo-editor 中将 Markdown 内容转成 asciidoc 格式
前端
狒狒AI8 小时前
Remotion / GSAP+Three / HyperFrames / Skia 四栈实测:代码渲染知识视频的选栈方法(附开源技能)
前端·人工智能·aigc
修炼的dance8 小时前
浏览器里导出H.265,8.5秒和55.5秒差在硬件
前端
补码缩写8 小时前
WebCodecs选编码器,探测之后还要验解码和播放
前端