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

Vuex原理

程序员文章站 2024-03-01 08:26:40
...

Vuex的原理

Vuex是专门为Vue.js应用程序设计的状态管理工具。相当于数据库mongoDB,MySQL等,任何组件都可以存取仓库中的数据。其中vuex类似的 还是有Redux,Redux大多用于React,针对Redux后续在做补充

Vuex运行机制

(1)Vuex的状态存储是响应式的
(2)当vue组件从store中读取时,若store中状态发生改变,响应的组件也会更新状态
(3)不能直接改变state,必须通过显示的提交(commit)mutations来追踪每个状态的变化

Vuex有什么好处?及使用场景

好处:可以做状态管理、采用localstorage保存信息、数据一直存储在用户的客户端中
使用场景:(1)登录信息、(2)购物车、(3)复杂的组件通信

vue的使用步骤

1、安装vuex

npm install vuex --save/-dev

2、引用vuex,创建仓库store。 创建 store.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

//数据
const state={
    count:10
}
//action  执行异步操作,不可以修改state数据
const actions={
    getParamSync (context,Object) {
	    //处理异步操作
        setTimeout(()=>{
	        //3.通过commit提交一个名为getParam的mutation
	        //action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation
            context.commit('increment',Object)
        },3000)
    }
}
//mutation 可直接修改state数据
const mutations={
    increment(state,value){
        state.count += value;
    },
    decrement(state,value){
        state.count -=value;
    }
}
//getter 
const getters = {
    newCount:state => state.count * 3
}
 
export default new Vuex.Store({
	state,
	mutations,
	actions,
	getters
})

3 . 在 main.js中注册到根组件中

import store from './store/store.js'
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

vuex的属性以及使用

  1. state - - - state是存储的单一状态,是存储的基本数据。

  2. getters - - - getters是store的计算属性,相当于组件中的computed的属性,getters返回的值会根据它的依赖被缓存起来,且只有当它的依赖值发生改变才会被重新计算,在组件中使用$store.getters.fun()

  3. mutations - - - 修改状态,并且是同步的。在组件中使用$store.commit(’’,params)

  4. actions - - - 异步操作 在组件中使用 $store.dispatch("")

  5. module - - -
    Module是store分割的模块,每个模块拥有自己的state、getters、mutations、actions

异步是怎么修改数据的

异步更改action,action中通过commit触发mutations进行数据更改
如图所示:
Vuex原理

vue和vuex的关系

vuex同样能和vue一样实现响应式
在vuex中

		state相当于组件中的data
		getters相当于computed
		mutations相当于methods

** 分享大家一下方式,将vuex每个部分拆分
运用vuex语法糖mapMutations**
motations.js

 const mutations = {
    SET_NEWS(state, val) {
        state.news = val
    }
}
export default mutations    

1、存储数据 ( a.vue文件 )

import { mapMutations } from "vuex"; // 引入mapMutations
export default {
	methods: {
		...mapMutations({
		    // 将changeNews与mutations中的SET_NEWS关联
		    changeNews: "SET_NEWS"
		}),
		submit(){
			// 提交一个名为changeNews的mutation,并传入参数val
			let val = 'test news';
			this.changeNews(val);// 相当于this.$store.commit("changeNews", val);
		}
	}
}

2、获取数据( b.vue文件 )

import { mapGetters } from "vuex"; // 引入mapGetters 
export default {
	computed: {
        // 用vuex读取数据(读取的是getters.js中的数据)
        // 相当于this.$store.getters.news(vuex语法糖)
        ...mapGetters(["news"])
	},
	created() {
        // 获取getters中news数据
        console.log(this.news);
	}
}

3、index.js

import Vue from 'vue'
import Vuex from 'vuex'
import * as actions from './actions'
import * as getters from './getters'
import state from './state'
import mutations from './mutations'
//每次修改state都会在控制台打印log
import createLogger from 'vuex/dist/logger'

Vue.use(Vuex)

const debug = process.env.NODE_ENV !== 'production'

export default new Vuex.Store({
	actions,
	getters,
	state,
	mutations,
	strict: debug, // 当debug=true时开启严格模式(性能有损耗)
	plugins: debug ? [createLogger()] : []
})

state.js

const state = {
	news: {}
}

export default state

mutations.js:

const mutations = {
	SET_NEWS(state, val) {
		state.news= val
	}
}

export default mutations

getters.js:

// 通常通过getters取数据 (this.$store.getters.news;)

export const news = state => state.news  // 不做其他处理 直接映射出去

actions.js

//异步处理
...

4.使用store

在main.js中引用

import store from './store' //vuex存储文件

...
...

new Vue({
	el: '#app',
	router,
	store,
	components: {
		App
	},
	template: '<App/>'
})

module综合用法

store.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
 
const test1 = {
  namespaced: true,
  state: {
    name: 'moduleA',
    type: 'module A'
  },
  mutations: {
    updateNameByMutation(state, appendStr){
      state.name = state.name + " append Str: " + appendStr
    }
  },
  actions: {
    udpateNameByAction({commit}, appendStr) {
      commit("updateNameByMutation", appendStr)
    }
  },
  getters: {
    getNameA(state){
      return state.name
    }
  }
}
const test2 = {
  // 当namespaced=true 时, vuex, 将会自动给各自module 添加访问路径名。 方便区分moduel
  namespaced: true,
  state:{
    name: 'moduleB',
    type: 'module B'
  },
  mutations: {
    updateNameByMutation(state, appendStr){
      state.name = state.name + " append Str: " + appendStr
    }
  },
  actions: {
    // 如果不使用命名空间, 那么view 指向actions 的该方法时,会执行所有与指定action名相同的函数(即:这里module A,B 中该action都会执行)
    udpateNameByAction({commit}, appendStr){
      commit("updateNameByMutation", appendStr)
    }
  },
  getters: {
    getNameB(state){
      return state.name
    }
  }
}
 
const storeInstall =  new Vuex.Store({
   state: {
     name: 'i am root state name'
   },
   modules:{
    // 这里的路径名: test1, test2, 在view 中 通过 mapActions('test1', [actionName]) 使用并区分需要使用的module
    test1,
    test2
   }
})
 
export default storeInstall

store.js 几个简单的vuex 使用场景模拟。 我们有多个模块,分别为: test1, test2… 。

   我们发现开发中可能会存在相同的stateName/ actionName/ mutaionName /。  (实际开发中,getterName 如果有重名编译会提示 getter 重名....)

  我们使用vuex 需要实例化一个Vuex的Store构造函数。 这里storeInstall 中第一个state, 我们可以理解为根 state, 它全局可访问。 modules 中则是我们自定义注册的module. 每个module 中都有自己独立的state, action, mutation, getter...  


  需要注意的是,这里通过给每个module 对象添加namespaced: true, 来达到命名空间来区分Module的效果。也是通过它来区分更新/调用 对应的vuex 方法来隔离未知数据更新等数据相关问题

vue组件

<template>
  <div>
    <div>
    <h2>Page Test1</h2>
    </div>
    <div>
    <a href="javascript:" @click="changeName">udpate: 名称Name</a>  &nbsp; &nbsp;
    <a href="javascript:" @click="showName">显示更新后的Name</a> &nbsp; &nbsp;
    </div>
  </div>
</template>
<script>
import { mapState, mapActions } from 'vuex'
export default {
  data(){
    return {}
  },
  computed: {
    ...mapState('test1', {
      state: state => state
    })
  },
  methods: {
    // test1 模块路径名
    ...mapActions('test1', [
      'udpateNameByAction'
    ]),
    changeName(){
      this["udpateNameByAction"]('ha ha test1 udpate !!')
    },
    showName(){
      console.log(this.$store.state)
    },
  },
  mounted() {
    console.log("store name: ", this.$store)
    console.log("namespace test1 state: ", this.state)
  }
}
</script>
 

关于vuex module 这里只是个基本讲解。 总结下来就是module 给了我们一种隔离vuex store 各个 state及相关api 的方法,让数据相关操作在复杂的项目场景可以更清晰,易追踪。

相关标签: vuex

上一篇: python实现rsa加密实例详解

下一篇: