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

总结

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

相关推荐
念念不忘 必有回响2 分钟前
viepress:vue组件展示和源码功能
前端·javascript·vue.js
C澒8 分钟前
多场景多角色前端架构方案:基于页面协议化与模块标准化的通用能力沉淀
前端·架构·系统架构·前端框架
崔庆才丨静觅9 分钟前
稳定好用的 ADSL 拨号代理,就这家了!
前端
江湖有缘11 分钟前
Docker部署music-tag-web音乐标签编辑器
前端·docker·编辑器
恋猫de小郭1 小时前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅8 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60619 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了9 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅9 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅9 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端