Vue<vuex在项目中的使用>

此篇文章是介绍利用 vuex 储存用户登录时的相关信息的使用方法。

声明:前面部分是刚开始对vuex的接触,后面部分是学习后对vuex使用的部分优化,想直接用最新的,可以直接找到 20200819 部分。

效果图:
image.png
使用方法:

相关配置文件


image.png

index.js

import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
Vue.use(Vuex)
export default new Vuex.Store({
    //模块引入
    modules:{
        user:user
    }
})

user.js


export const USER_SIGNIN = 'USER_SIGNIN' //登录成功
export const USER_SIGNOUT = 'USER_SIGNOUT' //退出登录
export const USER_INFO_COMMIT = 'USER_INFO_COMMIT' //配合sessionStorage解决vux刷新丢失问题
export default {
    // 存储状态(变量)
    state: {
        userInfo: {},//储存用户相关信息
        userLogin: false,//用户登录状态
    },
    // 对数据获取之前的再次编译,可以理解为state的计算属性 this.$store.getters.方法名。
    getters: {
      
    },
    // 修改状态,并且是同步的。在组件中使用$store.commit('',params)
    mutations: {
        //用户登陆方法
        [USER_SIGNIN](state, user) {
            //储存用户相关信息
            sessionStorage.setItem('userInfo', JSON.stringify(user))
            sessionStorage.setItem('userLogin', 'true')
            if (JSON.stringify(user)) {
                //解决用户信息未及时更新问题
                Object.assign(state.userInfo, sessionStorage.getItem('userInfo') ? JSON.parse(sessionStorage.getItem('userInfo')) : user)
                //更新用户登录状态
                state.userLogin = sessionStorage.getItem('userLogin') ? JSON.parse(sessionStorage.getItem('userLogin')) : false
            }
        },
        //用户退出登录方法
        [USER_SIGNOUT](state) {
            state.userLogin = false;
            state.userInfo = {};
            //清除sessionStorage内的所有记录
            sessionStorage.clear();
        },
        //解决浏览器刷新页面数据丢失问题(根据之前储存的sessionStorage相关信息来判断)
        [USER_INFO_COMMIT](state) {
            Object.assign(state.userInfo, sessionStorage.getItem('userInfo') ? JSON.parse(sessionStorage.getItem('userInfo')) : {})
            state.userLogin = sessionStorage.getItem('userLogin') ? JSON.parse(sessionStorage.getItem('userLogin')) : false;
        },
    },
    // 异步操作
    actions: {
        [USER_SIGNIN]({ commit }, user) {
            commit(USER_SIGNIN, user)
        },
        [USER_SIGNOUT]({ commit }) {
            commit(USER_SIGNOUT)
        },
        [USER_INFO_COMMIT]({ commit }) {
            commit(USER_INFO_COMMIT)
        }
    }
}

main.js

import store from './store/index' //引入

/* eslint-disable no-new */
new Vue({
  el: '#app',
  store, //引入
  router,
  components: { App },
  template: '<App/>'
})

配置完成后,就可以直接在vue组件中使用

xxx.vue组件

<template>
  <div style="margin:200px 0">
    <p>登录状态:{{userLogin}}</p>
    <p>用户信息:{{userInfo}}</p>
    <button @click="loginIn()">登录</button>
    <button @click="loginOut()">退出</button>
  </div>
</template>

<script>
export default {
  computed: {
    userLogin() {
      if (this.$store.state.user.userLogin) {
         return this.$store.state.user.userLogin;
      } else {
        this.$store.commit("USER_INFO_COMMIT");
        return this.$store.state.user.userLogin;
      }
    },
    userInfo() {
      if (this.$store.state.user.userLogin) {
        return this.$store.state.user.userInfo;
      } else {
        this.$store.commit("USER_INFO_COMMIT");
        return this.$store.state.user.userInfo;
      }
    }
  },
  data() {
    return {
      userMsg: {
        name: "小明",
        age: "18",
        sex: "男"
      }
    };
  },
  methods: {
    loginIn() {
      this.$store.commit("USER_SIGNIN", this.userMsg);
    },
    loginOut() {
      this.$store.commit("USER_SIGNOUT");
    }
  }
};
</script>

<style>
</style>

🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊🌊

20200819代码优化调整:

程序员都是在不断成长的,下面的代码是针对之前使用vuex的部分优化。


image.png

模块引入
相比之前的模块引入,这边也是同样按照 modules 目录下,进行的配置。不过是直接通过遍历文件目录实现的,不需要再一个个去写了。

index.js

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

Vue.use(Vuex)
// 把modules文件下的 js文件返回出来
// https://webpack.js.org/guides/dependency-management/#requirecontext
const modulesFiles = require.context('./modules', true, /\.js$/)

// you do not need `import app from './modules/app'`
// it will auto require all vuex module from modules file
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
  // set './app.js' => 'app'
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {})

const store = new Vuex.Store({
  modules,
  getters
})

export default store

getters.js
getters.js里面是所有你想对外报漏的数据

const getters = {
    name: state => state.user.name,
    phoneNo: state => state.user.phoneNo,
}
export default getters

user.js
login, logout, getInfo 相当于针对用户的一些api接口;(可以忽视掉)

state 里面储存的为用户token,name和phoneNo,其中在getters.js里面,可以实现了针对 user 模块内 name和phoneNo 数值的对外暴露

mutations 里面实现了重置用户信息,储存用户token,储存name,储存phoneNo的修改方法;

actions 里面是针对用户登录,获取用户信息,以及用户退出登陆的异步方法。此处你会看到有使用 Promise 异步操作,主要用于使用过程中的 await数据等待处理。 不太理解async/await 的可 参考此篇文章

namespaced: true,主要是为了解决不同模块命名冲突的问题,将不同模块的namespaced:true,之后在不同页面中引入getter、actions、mutations时,需要加上所属的模块名。

类似这样,就可以在使用页面内,直接对vuex内,user模块内的login用户登陆方法进行调用。
this.$store.dispatch("user/login");


import { login, logout, getInfo } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'

const getDefaultState = () => {
    return {
        token: getToken(),
        name: "",
        phoneNo: "",
    }
}

const state = getDefaultState()

const mutations = {
    RESET_STATE: (state) => {
        Object.assign(state, getDefaultState())
    },
    SET_TOKEN: (state, token) => {
        state.token = token
    },
    SET_NAME: (state, name) => {
        state.name = name
    },
    SET_PHONENO: (state, phoneNo) => {
        state.phoneNo = phoneNo
    },
}

const actions = {
    // 用户登录,获取token,并储存到cookie里面
    login({ commit }, userInfo) {
        return new Promise((resolve, reject) => {
            commit('SET_PHONENO', '15518270529')
            resolve()
            // //调用登录接口
            // login().then(response => {
            //     const { data } = response
            //     // 储存到cookie里面
            //     commit('SET_TOKEN', data.token)
            //     setToken(data.token)
            //     resolve()
            // }).catch(error => {
            //     reject(error)
            // })
        })
    },
    //调用获取用户信息的接口
    getInfo({ commit, state }) {
        return new Promise((resolve, reject) => {
            //调用获取用户信息接口
            getInfo().then(response => {
                const { data } = response
                if (!data) {
                    reject('Verification failed, please Login again.')
                }
                const { name, phoneNo } = data
                commit('SET_PHONENO', phoneNo)
                commit('SET_NAME', name)
                resolve(data)
            }).catch(error => {
                reject(error)
            })
        })
    },
    //用户退出登录
    logout({ commit, state }) {
        return new Promise((resolve, reject) => {
            logout(state.token).then(() => {
                removeToken() // must remove  token  first
                commit('RESET_STATE')
                resolve()
            }).catch(error => {
                reject(error)
            })
        })
    },
}

export default {
    namespaced: true,
    state,
    mutations,
    actions
}

xxx.vue组件

import { mapGetters } from "vuex";
//计算属性
 computed:{
   //通过getter.js对外暴露的 phoneNo 值进行使用
   // {{phoneNo}} 数值使用
    ...mapGetters(['phoneNo'])
  },
  methods: {
    async isLogin() {
    //使用 try/catch 抓取错误信息,如果登陆失败则会输出错误信息,不往下执行
      try {
        await this.$store.dispatch("user/login");
        //如果登陆成功才会 输出 ‘登陆成功’
        console.log('登陆成功')
      } catch (error) {
        console.log(error);
      }
    }
  }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容