vuex使用总结

学习用例是在github上找的demo,在原来的基础上学习和总结

源demo地址:https://github.com/lzxb/vue2-demo

里面有安装教程,但是这个demo无法使用es6 的异步方法(会报$export is not a function 错误),需要安装polyfill环境,具体安装和配置的方法如下:

npm install --save @babel/polyfill

安装后需要在webpack.config.js中module.exports中做如下修改

entry: ['@babel/polyfill','./src/main.js'], //编译入口文件

重新启动服务,就可以使用es6了

vuex的流程图如下:

vuex在概念上与react的flux有点类似,由dispach去指派action,action会触发commit调用mutations中的代码,从而改变store中的状态,重要的是vuex的store采用的是模块化的管理,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割

这里模块化的管理的意思就是,你可以定义多个js文件,每个js文件中都可以拥有一套去改变store的方法,如项目中的user.js和index.js,他们是嵌套的关系,就是在index中建立全局store,将uesr作为其中的一个模块导入其中,那么就可以直接去调用user中的action,当然这里你可以仿写user.js再定义一些其他的处理函数,导入到index.js中,这样就实现了模块化的管理方式了。

index.js部分代码

modules: {
        user
    },

这时我们清楚了模块化的定义后再来开始走一下改项目的流程,目的是知道如何去实现vuex的调用过程的

首先是登录界面,这里不再详细说明路由的过程了,可以参考我的上篇博客

在login.vue页面主要js代码

 <script>
    import { mapActions } from 'vuex'
    import { USER_SIGNIN } from 'store/user'
	import store,{TEST_OUT,actionA,actionC} from 'store/index'
    export default { 	
        data() {
			return {
				btn: false, //true 已经提交过, false没有提交过
				form: {
					id: '',
					name: ''
				}
			}
		},
		methods: {
            ...mapActions([USER_SIGNIN, TEST_OUT]),
			submit() {
				this.btn = true
				if(!this.form.id || !this.form.name) return
                //以下三种调用action的方法都是对的
				this.USER_SIGNIN(this.form)
				// store.dispatch(USER_SIGNIN,this.form)
				this.$store.dispatch(USER_SIGNIN,this.form)
				this.$router.replace({ path: '/home' })
			},
			sendTest(){
				store.dispatch(actionC)
				// store.dispatch(TEST_OUT)
			}
		}
    }
</script>'

在这里主要是引入关键字,声明action,函数dispatch各个action,这里很好理解,注意点是这里有三种调用action的方法,

this.USER_SIGNIN(this.form)//声明action后可直接使用this指针调用,但需要以函数的方式调用
store.dispatch(USER_SIGNIN,this.form)//需要引入store,直接用dispach掉用
this.$store.dispatch(USER_SIGNIN,this.form)//vuex将store挂载到系统中,不需要去引入,可直接使用

下面是各个action的定义user.js

import Vue from 'vue'

export const USER_SIGNIN = 'USER_SIGNIN' //登录成功
export const USER_SIGNOUT = 'USER_SIGNOUT' //退出登录

export default {
    state: JSON.parse(sessionStorage.getItem('user')) || {},
    mutations: {
        [USER_SIGNIN](state, user) {
            sessionStorage.setItem('user', JSON.stringify(user))
            Object.assign(state, user)
        },
        [USER_SIGNOUT](state) {
            sessionStorage.removeItem('user')
            Object.keys(state).forEach(k => Vue.delete(state, k))
        }
    },
    actions: {
        [USER_SIGNIN]({commit}, user) {
            commit(USER_SIGNIN, user)
        },
        [USER_SIGNOUT]({commit}) {
            commit(USER_SIGNOUT)
        }
    }
}

这里如果sessionStorage中有user将其取出,放入到state中,action中是标准的模块化的写法(带参和无参),由commit触发mutation中的函数触发对state的修改

登录后的跳转home页面,在页面使用mapstate去获取state的数据赋值到该页面的变量中

<style lang="less" scoped>

</style>
<template>
	<div>
		<v-header title="首页">
			<router-link slot="left" to="/">首页</router-link>
			<router-link slot="right" to="/signout">退出</router-link>
		</v-header>
		<div style="padding: 50px;">{{user.name}}欢迎回家</div>
	</div>
</template>
<script>
    import { mapState } from 'vuex'
    export default {
        computed: mapState({ user: state => state.user }),//将state 的数据赋值本地
    }
</script>

该页面可以直接使用state的数据

以上就是vuex的流程,很简单,但是里面也有很多东西需要注意,比如mutation中的函数是无法异步的等,如果需要更加细致的说明,点这里

action是可以异步的,所以我们在实际开发中如果需要异步去完成一个很复杂的操作,不妨可以试试异步的action,这里我在index.js中使用了异步的方法,仅供参考

import Vue from 'vue'
import Vuex from 'vuex'
import user from './user'

export const TEST_OUT = 'TEST_OUT' //测试输出
export const actionA = 'actionA' //测试输出
export const actionB = 'actionB' //测试输出
export const actionC = 'actionC' //测试输出
Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        todos: [
          { id: 1, text: '123', done: true },
          { id: 2, text: '456', done: false }
        ]
      },
    strict: process.env.NODE_ENV !== 'production', //在非生产环境下,使用严格模式
    getters:{
        doneTodos: state => {
            return state.todos.filter(todo => todo.done)
          }
    },
    modules: {
        user
    },
    computed: {
        doneTodosCount () {
         console.log( this.$store.getters.doneTodos);
        }
    },
    actions:{
        [TEST_OUT]({commit}){
            commit(TEST_OUT)
        },
        [actionB]({commit}){
            commit(actionB)
        },
        // 在C中调B,B完成掉A
        async [actionC]({dispatch,commit}){
            await dispatch('actionB')
            commit(actionA)
        },
        // 在A中调B等B完成时调用C
        [actionA]({dispatch,commit}){
            return dispatch('actionB').then(()=>{
                commit(actionC)
            })
        }
    },
    mutations:{
        [TEST_OUT](state){
            console.log(this.getters.doneTodos);
            console.log(state);
        },
        [actionC](state){
            console.log('this is c');
        },
        [actionB](state){
            console.log('this is b');
        },
        [actionA](state){
            console.log('this is a');
        }
    }
})

参考登录界面的调用方法,我定义了一个按钮去调用该文件的actionA和actionC,actionA使用的是promise的调用方式,而action使用的是es6的async/await异步调用方式,均可以获取到想要的输出。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值