vueX学习总结

242 阅读1分钟

一 使用

1.1安装:npm install vuex --save

1.2在src目录下创建一个store文件夹并在store文件夹下创建一个index.js文件

文件内容如下

import Vuex from'vuex';
import Vue from 'vue';
 Vue.use(Vuex);
//创建仓库
 const store Vuex.Store({
   //数据
       state: {
          test_data: “this is some test data”,
          color: “light-green”
        },
        //修改值得方法
         mutations: {
           setColor(state, coLor) {
               state.color= color;
           },
          Action:{
              login({commit}, username) {
                return new Promise((resolve, reject) => {
                	setTimeout(() => {
                		if (username === 'admin') {
                			commit('setColor',res.data.data)//调用上方mutations中setColor方法修改数据
                			resolve()
                		} else {
                			reject()
                		}
                	}, 1000);
                })
              }
          },
          modules: {//模块化使用modules定义多个子模块利于组件复杂状态
            user,
          }
  }
export default store

1.3:main.js加载和挂载

import stort from  './store/index'
new Vue({
   el: ‘#app’, 
   router,
   store,
   components: { App }, 
  template: ‘<App!>’
})

1.4:使用

① 修改

//第一个参数为mutations下的方法,二为参数
//不用加载任何vuex的文件main.js中已经全局加载了
this.$store.commit('setColor',res.data.data)

② 使用

this.$store.state.color

③Action派发

this.$store.dispatch('login', 'admin').then(() => {
    this.$router.push(this.$route.query.redirect)
}).catch(() => {
    alert('用户名或密码错误')
})

④模块化

user.js 定义

export default {    
    namespaced: true, // 避免命名冲突    
    // ...
}  

访问方式响应变化

// Login.vue
<button @click="login" v-if="!$store.state.user.color">登录</button>  //多上一个文件名$store.state.user.color和$store.state.color
this.$store.dispatch('user/login', 'admin').then(() => {
    const redirect = this.$route.query.redirect || '/'
    this.$router.push(redirect)
}).catch(() => {
	alert('用户名或密码错误')
})

import { mapState,mapGetters,mapMutations,mapActions} from 'vuex'
computed:{
  ...mapState(['color'])
}
methods:{
   ...mapActions(['setC'])
}
//模块化
...mapState({'name':state=>state.coalgas.token}),
//或者
...mapState('coalgas',['token']),
...mapActions({Login:'coalgas/Login' }),
//或者
...mapActions('coalgas',['Login']),

二 原理

2.1 index.js文件说明

下方文件可以看出vueX是用的new,说明./kvueX.JS文件中是一个构造函数或者类,传入的参数是一个对象。

import Vue from 'vue';
import VueX from './vueX'
Vue.use(VueX);
export default new VueX.store({
	state :{
		counter :0
	},
	getters:{
		doubleCounter(state){
			return state.counter*2
		}
	},
	mutations:{
		add (state){
			state.counter++
		}
	},
	actions:{
		add({commit}){
			setTimeout(()=>{
				commit('add')
			},1000)
		}
	},
	modules:{
		
	}
})

2.2vueX文件说明

​ 首先声明一个全局变量let vue,这是一个插件,在加入vue中都会执行install方法,并且将vue传入。我们用 Vue=_Vue;将前方声明的全局变量赋值为vue。接下来通过混入的方法将所有的组件种豆混入生命周期函数beforeCreate和原有的合并,判断在根实例后将store挂载到Vue的原型属性上。

​ constructor函数首先对参数进行解析并挂在到原型属性上,通过new Vue的方法将参数中存储数据的参数响应化挂载带实例属性上。将两个函数也挂载到原型属性上。

​ commit函数,首先第一个参数为用法调用时传入的方法名,第二个参数为用法响应修改的值,通过解析参数拿到用法想要调的方法mutations中的方法,如果方法存在调用方法,传入的第一个参数为响应数据,第二位用法传入的数据。

​ dispath函数和commit函数基本一样不过在调用actions中的方法时传入的第一个参数为this,也就是vuex对象。

let Vue;
class Store{
	constructor(options){
		this._mutations=options.mutations;
		this._action=options.actions;
		this.state=new Vue({
			data:options.state
		})
		this.commit=this.commit.bind(this)
		this.dispath=this.dispath.bind(this)

	}
	commit(type,payload){
		const entry=this._mutations[type]
		if(entry){
			entry(this.state,payload)
		}
	}
	dispath(type,payload){
		const entry = this ._action[type]
		if(entry){
			//此处第一个参数是this,也就是vuex对象,所以在index中使用可以解构 {commit,dispatch,state}
			entry(this,payload)
		}
	}
}
function install(_Vue){
	Vue=_Vue;
	Vue.mixin({
		beforeCreate(){
			if(this.$options.Store){
				Vue.prototype.$Store=this.$options.store
			}
		}
	})
}
export default{
	Store,
	install
}