Vuex原理

Vuex是专门为Vuejs应用程序设计的状态管理工具,其实是集中的数据管理仓库,相当于数据库mongoDB等,任何组件都可以存取仓库中的数据。

1.Vuex框架运行流程
在这里插入图片描述
如上图Vuex:
Vuex的组成部分:
state:是存储的基本数据。
mutations:提交更改数据。
getter:对state加工,和computed计算属性一样。
actions:处理异步,通过store.commit方法触发mutations中的方法,从而改变state值。
module:是store分割的模块,每个模块拥有自己的state、mutations、getters、actions。

Vue组件接收交互行为,调用dispatch方法触发action相关处理,若页面状态需要改变,则调用commit方法提交mutation修改state,通过getters获取到state新值,提供了mapState、MapGetters、MapActions、mapMutations等辅助函数给开发在vm中处理store,重新渲染Vue Components,页面随之更新。

目录结构
在这里插入图片描述
module:提供module对象与module对象树的创建功能;

plugins:提供开发辅助插件,如“时间穿梭”功能,state修改的日志记录功能等;

helpers.js:提供action、mutation以及getters的查找API;

index.js:是源码主入口文件,提供store的各module构建安装;

store.js:提供了store在Vue实例上的装载注入;

util.js:提供了工具方法如find、deepCopy、forEachValue以及assert等方法。

三、那vuex和vue的响应式?

vue中的data、methods、computed,可以实现响应式。
在vue中,我们触发点击事件,就能触发methods中的方法,更改data的值,一旦数据发生变化,computed中的函数把数据能更新到视图。
那么computed是如何更新的?其实就是vue的双向绑定原理了。
computed中的计算属性getter生成唯一的watcher—>访问computed中的方法时,会将Dep.target指向它的watcher–>在方法中访问this.XX,会调用get方法,新增watcher到dep中—>设置时,会调用set方法触发dep.notify实现视图更新。

vuex实现同样的功能。vuex中的四部分与vue的对应关系:
state—>data、mutations—>methods、getters—>computed、actions:为了处理异步,不能直接更新state,需要借助mutations.
在VUEX中通过dispatch可以触发actions中的方法,②actions中的commit可以触发mutations中的方法。从而实现state的更新。

//store.js
const store =  new Vuex.Store({
    
    state: {
        count: 0
    },
    
    //第三步:改变state值,state的值只能通过mutations来修改
    mutations: {
        increment(state) {
            state.count++
        }
    },
    
   //第二步:this.$store.commit("increment")触发mutations中函数"increment"
    actions: {
        increment({commit}) {
             commit("increment"); //this.$store.commit("increment")
        }
     
    },
    
   //第四步:通过getter中的方法来获取state值
    getters: {
        getCount(state) {
            return state.count
        }
    }
    })
     
    export default store




//App.vue
<template>
      <div id="app">
            <button @click="increment">增加</button>
            {{this.$store.getters.getCount}}
      </div>
    </template>
     
    <script>
    export default {
        methods: {
        increment(){
                //第一步:this.$store.dispatch("increment")触发actions函数"increment"
                this.$store.dispatch("increment")
            }
        }
    }
    </script>


四、vuex的原理
1)每一个vue的插件,都需要一个公开的install方法,vuex也不例外

// src/store.js
export function install (_Vue) {
  if (Vue && _Vue === Vue) {
    return
  }
  Vue = _Vue
  applyMixin(Vue)//在所有组件的beforeCreate注入了设置this.$store这样的一个对象,
  //在任意组件中执行this.$store都能找到store对象
}

2)Vuex.Store的构造函数中,有一堆初始化以及resetStoreVM(this,state)整个vuex的关键。

// src/store.js
function resetStoreVM (store, state, hot) {
  // 省略无关代码
  Vue.config.silent = true
  //本质:将我们传入的state作为一个隐藏的vue组件的data
  //也就是说,我们的commit操作,本质上其实是修改这个组件的data
  store._vm = new Vue({
    data: {
      $$state: state
    },
    computed
  })
}
//this.$store._vm.$data.$$state===this.$store.state

五辅助函数
1)mapState辅助函数
当一个组件需要获取多个状态时,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,可以使用mapState辅助函数来帮助我们生成计算属性。当映射的计算属性名称与state的子节点名称相同时,我们也可以给mapState传一个字符串数组。

computed: mapState([
  // 映射 this.count 为 store.state.count
  'count'
])// {count: 1}
//mapState返回的是一个对象,我们也可以使用对象展开符获取
computed: {
    ...mapState(['selectedCard', 'count']), 
  }

2)mapGetters辅助函数
mapGetters辅助函数仅仅是将store中的getter映射到局部计算属性:

import { mapGetters } from 'vuex'

export default {
  // ...
  computed: {
  // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters([
      'doneTodosCount',
      'anotherGetter',
      // ...
    ])
  }
}

3)vuex namespaced的作用以及使用方式
vuex中的store分模块管理,需要在store的index.js中引入各个模块,为了解决不同模块命名冲突的问题,将不同模块的namespaced:true,之后在不同页面中引入getter、actions、mutations时,需要加上所属的模块名

前端群,有需要一起学习的加:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值