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还没有,当然要报错了。哦哦哦,原来如此,也算又搞明白了一点。

总结

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

相关推荐
深念Y25 分钟前
我明白为什么B站没法在浏览器开直播了——Windows Chrome推流踩坑全记录
前端·chrome·webrtc·浏览器·srs·直播·flv
zhangxingchao36 分钟前
AI应用开发七:可以替代 RAG 的技术
前端·人工智能·后端
Sun@happy1 小时前
现代 Web 前端渗透——基础篇(1)
前端·web安全
希冀1231 小时前
【CSS学习第十一篇】
前端·css·学习
隔窗听雨眠1 小时前
doctype、charset、meta如何控制整个渲染流水线
java·服务器·前端
kyriewen2 小时前
写组件文档写到吐?我用AI自动生成Storybook,同事以后直接抄
前端·javascript·面试
excel2 小时前
🧠 Prisma 表名大写 vs SQL 导出小写问题深度解析(附踩坑与解决方案)
前端·后端
周淳APP2 小时前
【前端工程化原理通识:从源头到运行时的理论阐述】
前端·编译·打包·前端工程化
五点六六六2 小时前
你敢信这是非Native页面写出来的渐变效果吗🌝(底层原理解析
前端·javascript·面试
tedcloud1233 小时前
TradingAgents部署教程:打造AI量化分析工作流
服务器·前端·人工智能·系统架构·edge