美文网首页
实现一个简单的vuex

实现一个简单的vuex

作者: 杨晨1994 | 来源:发表于2020-04-27 14:01 被阅读0次

首先我们先看下vuex的使用方式一般都是下面这样的

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
  state: {
    count:0
  },
  mutations: {
    changeCount (state,num) {
      state.count += num
    }
  },
  actions: {
    changeCount (context,num) {
      setTimeout(()=>{
        context.commit('changeCount',num)
      },2000)
    }
  },
  getters: {
    doubleCount (state){
      return state.count*2
    }
  }
})

有个组件是这样的

<template>
  <div>
    <div>数量--{{$store.state.count}}</div>
    <div>双倍数量--{{$store.getters.doubleCount}}</div>
    <button @click="handleClick">点击加1</button>
    <button @click="deferHandleClick">点击延迟加2</button>
  </div>
</template>

<script>
export default {
  name: 'Home',
  methods:{
    handleClick () {
      this.$store.commit('changeCount',1)
    },
    deferHandleClick () {
      this.$store.dispatch('changeCount',2)
    }
  }
}
</script>

我们要实现一个vuex主要有几个要点

  • vuex是一个插件,通过Vue.use使用
  • vuex里面有一个store类
  • 实现state,mutations,actions,getters
  • state改变的时候 通知组件数据变更

首先vuex是这样使用的


image.png

vuex里面有一个Store类,然后知道vuex是一个插件,通过Vue.use使用。
那么我们新建一个kVuex.js,代码里面应该有个Store类和一个install方法,大概是这样的

class Store {
}
function install(_vue) { // install方法接受一个vue的形参
}
export default {Store,install}

我们的main.js是这样的 把引入的store挂载到了vue根组件上

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

所以我们的install方法是这样的

let Vue; 
class Store {
}
function install(_vue) {// 接受一个参数 是vue
 Vue = _vue // 这里我们保存一下vue 一会还要用
  Vue.mixin({ // Vue构造器注入beforeCreate方法
    beforeCreate() {
      if(this.$options.store){ // 因为在上面代码中store只挂载到了根组件 所以下面的代码只在根组件执行
        Vue.prototype.$store = this.$options.store
      }
    }
  })
}
export default {Store,install}

现在我们开始实现state,要知道我们的state是响应式的,state发生变化的时候,组件会发生变化

let Vue;
class Store {
  constructor (options){
    this.state = new Vue({ // 利用vue的数据响应式原理 这也是为什么vuex只能在vue里用的原因
      data:{
        state:options.state
      }
    })
  }
}
function install(_vue) {
  Vue = _vue
  Vue.mixin({
    beforeCreate() {
      if(this.$options.store){
        Vue.prototype.$store = this.$options.store
      }
    }
  })
}
export default {Store,install}

实现mutations我们只需要加个映射就可以,但是我们是通过commit调用的,所以我们要实现commit方法

let Vue;
class Store {
  constructor (options){
    this.state = new Vue({ // 利用vue的数据响应式原理
      data:options.state
    })
    this.mutations = options.mutations;//传进来的mutations
  }
  commit = (type,arg)=>{ // commit方法接受一个类型和参数 类型就是你调用的时候传的方法名
    // 在组件里我们是这样用的this.$store.commit('changeCount',1)
    this.mutations[type](this.state,arg) // 执行mutations里面的方法
  }
}
function install(_vue) {
  Vue = _vue
  Vue.mixin({
    beforeCreate() {
      if(this.$options.store){
        Vue.prototype.$store = this.$options.store
      }
    }
  })
}
export default {Store,install}

实现actions一样也是加个映射关系。但是我们还要实现dispatch方法

let Vue;
class Store {
  constructor (options){
    this.state = new Vue({ // 利用vue的数据响应式原理
      data:options.state
    })
    this.mutations = options.mutations;//传进来的mutations
    this.actions = options.actions;//传进来的actions
  }
  commit = (type,arg)=>{ // commit方法接受一个类型和参数 类型就是你调用的时候传的方法名
    // 在组件里我们是这样用的this.$store.commit('changeCount',1)
    this.mutations[type](this.state,arg) // 执行mutations里面的方法
  }
  dispatch (type,arg) {// dispatch方法接受一个类型和参数 类型就是你调用的时候传的方法名
    this.actions[type]({
      commit:this.commit
    },arg)
  }
}
function install(_vue) {// 接受一个参数 是vue
  Vue = _vue // 这里我们保存一下vue 一会还要用
  Vue.mixin({ // Vue构造器注入beforeCreate方法
    beforeCreate() {
      if(this.$options.store){ // 因为在上面代码中store只挂载到了根组件 所以下面的代码只在根组件执行
        Vue.prototype.$store = this.$options.store
      }
    }
  })
}
export default {Store,install}

实现getters 就不能简单的加个映射了

let Vue;
class Store {
  constructor (options){
    this.state = new Vue({ // 利用vue的数据响应式原理
      data:options.state
    })
    this.mutations = options.mutations;//传进来的mutations
    this.actions = options.actions;//传进来的actions
    this.getters = {}; //添加getters为{}
    options.getters && this.handleGetter(options.getters) // 当传入的getters存在的话 执行handleGetter
  }
  commit = (type,arg)=>{ // commit方法接受一个类型和参数 类型就是你调用的时候传的方法名
    // 在组件里我们是这样用的this.$store.commit('changeCount',1)
    this.mutations[type](this.state,arg) // 执行mutations里面的方法
  }
  dispatch (type,arg) {// dispatch方法接受一个类型和参数 类型就是你调用的时候传的方法名
    // 在组件里我们是这样用的this.$store.dispatch('changeCount',2)
    this.actions[type]({  // 执行actions里面的方法
      commit:this.commit
    },arg)
  }
  handleGetter (getters){
    Object.keys(getters).forEach(key=>{ // 拿出getters的key做一个循环
      Object.defineProperty(this.getters,key,{ // 给this.getter添加属性,属性名为key这个变量,并添加get方法
        get: ()=> {
          return getters[key](this.state) // 执行getters里面的方法传参   并return出去
        }
      })
    })
  }
}
function install(_vue) {// 接受一个参数 是vue
  Vue = _vue // 这里我们保存一下vue 一会还要用
  Vue.mixin({ // Vue构造器注入beforeCreate方法
    beforeCreate() {
      if(this.$options.store){ // 因为在上面代码中store只挂载到了根组件 所以下面的代码只在根组件执行
        Vue.prototype.$store = this.$options.store
      }
    }
  })
}
export default {Store,install}

到此我们这个简单的vuex就完成了

相关文章

  • 手摸手教你实现一个 vuex

    参考链接:如何实现一个简单的vuex

  • 实现一个简单的vuex

    首先我们先看下vuex的使用方式一般都是下面这样的 有个组件是这样的 我们要实现一个vuex主要有几个要点vuex...

  • Vue vuex简单实现

  • 手动实现简单的vuex

    官方vuex vue add vuex main.js kstore.js kvuex.js 使用

  • vuex

    Vuex介绍: Vuex官网:http://vuex.vuejs.org/ Vuex是实现数据状态管理的技...

  • Vuex简单入门

    今天试了一下Vuex,感觉跟Redux的实现思想类似。再此,简单地总结一下。 什么是Vuex 在Vue中,多组件的...

  • 【教程】vue加element -ui实现表格增删改功能

    vue+elenent-ui+vuex实现增删改功能 这是一个简单的增加、删除、修改功能的表格 新人报道 如果那里...

  • 详解如何实现一个简单的 vuex

    首先我们需要知道为何要使用 vuex。父子组件通信用 prop 和自定义事件可以搞定,简单的非父子组件通信用 bu...

  • Vuex 基础

    零、场景说明通过vuex实现计数器的功能 一、入口文件进入vuex 二、入口文件修改 new一个vuex的Stor...

  • vuex的简单应用01

    二、简单的从store中取值 三、简单的改变vuex中的值 三.1 简单的改变vuex中的值--传递一个参数 三....

网友评论

      本文标题:实现一个简单的vuex

      本文链接:https://www.haomeiwen.com/subject/znhjwhtx.html