欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

手写一个简易版的 vuex(支持 state,getters,mutations,actions)

程序员文章站 2022-04-02 17:47:18
...

手写一个简易版的 vuex(支持 state,getters,mutations,actions)

简介:vuex 相信大家都用过,内部到底是如何实现的呢,我根据源码以及一些参考资料,手写了一个简易版的 vuex,供大家参考。

本文github 源码地址

下面是实现步骤

1.项目依赖:(先安装,步骤略)
package.json

{
  "name": "vue-my-vuex",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "core-js": "^3.6.4",
    "vue": "^2.6.11",
    "vuex": "^3.1.3"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.3.0",
    "@vue/cli-plugin-eslint": "~4.3.0",
    "@vue/cli-plugin-vuex": "^4.3.1",
    "@vue/cli-service": "~4.3.0",
    "babel-eslint": "^10.1.0",
    "eslint": "^6.7.2",
    "eslint-plugin-vue": "^6.2.2",
    "vue-template-compiler": "^2.6.11"
  }
}

2.项目目录结构
手写一个简易版的 vuex(支持 state,getters,mutations,actions)
3.核心代码
/src/store/Vuex.js

export let Vue
function install(_Vue) {
  Vue = _Vue

  Vue.mixin({
    beforeCreate() {
      // 在vue原型上注册$store
      if (this.$options.store) {
        Vue.prototype.$store = this.$options.store
      }
    }
  })
}

class Store {
  constructor(options) {
    this.$option = options

    // 使用vue实例使state响应式
    this.state = new Vue({
      data: options.state
    })

    // 保存options里的mutations,actions
    this.mutations = options.mutations || {}
    this.actions = options.actions || {}

    // 实现getters
    this.getters = {}
    // 使getters响应式
    Object.keys(options.getters).forEach(key => {
      Object.defineProperty(this.getters, key, {
        get: () => {
          return this.state[key]
        },
        enumerable: true
      })
    })
  }

  // 实现commit方法
  commit(type, pyload) {
    this.mutations[type](this.state, pyload)
  }

  // 实现dispatch方法
  dispatch(type, pyload) {
    this.actions[type](
      {
        state: this.state,
        commit: this.commit.bind(this)
      },
      pyload
    )
  }
}

export default { Store, install }
/**
 * 这样导出 相当于
 * const Vuex={Store,install}
 * export default  Vuex
 *
 *之所以这样导出 是因为使用的时候是 new Vuex.Store()
 */

/src/App.vue

<template>
  <div id="app">
    <h1>App 组件</h1>
    <div>计数:{{ $store.state.count }}个</div>
    <div>getters计数:{{ $store.getters.count }}个</div>
    <button @click="add">commit加</button>
    <button @click="dispatchAdd">dispatch加</button>

    <HelloWorld msg="Welcome to Your Vue.js App" />
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  },
  methods: {
    add() {
      this.$store.commit('ADD_COUNT', 100)
    },
    dispatchAdd() {
      this.$store.dispatch('addCount', 1)
    }
  }
}
</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>

/src/components/HelloWorld.vue

<template>
  <div class="hello">
    <h1>HelloWorld 组件</h1>
    {{ $store.state.count }}
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  }
}
</script>


4.实现效果
手写一个简易版的 vuex(支持 state,getters,mutations,actions)

参考链接

1.https://github.com/vuejs/vuex

2.https://github.com/57code/vue-study