Vuex系列---【Vuex实现登录页共享用户信息及解决浏览器刷新Vuex数据消失问题】
index页面时一个登录页,输入信息之后点提交。之后跳转到main页面,该页面需要展示登录页输入的账号,下面用vuex实现账号数据的保存和共享,分别展示了模块化和非模块化的代码展示
目录结构:
代码实现:
index.vue---登录页
<template> <div class="box"> <h1>登录</h1> <el-form :model="ruleForm" ref="ruleForm" label-width="100px" class="demo-ruleForm"> <el-form-item label="账号" prop="name"> <el-input type="text" v-model="ruleForm.name" autocomplete="off" size="mini"></el-input> </el-form-item> <el-form-item label="密码" prop="pass"> <el-input type="text" v-model="ruleForm.pass" autocomplete="off" size="mini"></el-input> </el-form-item> <el-form-item label="手机号" prop="phone"> <el-input v-model.number="ruleForm.phone" size="mini"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm()">提交</el-button> <el-button @click="resetForm('ruleForm')">重置</el-button> </el-form-item> </el-form> </div> </template> <script> export default { name:'Index', data(){ return { ruleForm: { name: '', pass: '', phone: '' }, } }, methods: { // 重置表单 resetForm(formName) { this.$refs[formName].resetFields(); }, // 提交表单 submitForm() { // 调用store中actions方法,用dispatch this.$store.dispatch('asyncUpdateUser',{name:this.ruleForm.name}); this.$router.push({name:'main'}) } } } </script> <style> .box { width: 600px; height: 400px; border: 1px solid #ccc; margin: auto; } .box .el-input { position: relative; font-size: 14px; display: inline-block; width: 50%; } </style>
2.main.vue ---- 展示账号页
<template> <div> <!-- 如果不做处理,页面刷新该值消失,回到最初定义的空值中(store定义的是'') --> <!-- 1.问题描述:vuex的状态存储是响应式的,当vue组件从store中读取状态的时候,若store中的状态发生变化,那么相应的组件也会相应的得到高效更新,但是有一个问题,vuex的存储的数据只是在页面中的,相当与我们定义的全局变量,刷新之后,里边的数据就会恢复到初始化状态 --> <!-- 2.解决思路:监听页面是否刷新,如果页面刷新了,将state对象存入到sessionStorage中,页面打开之后,判断sessionStorage中是否存在state对象,如果存在,则说明页面是被刷新过的,将sessionStorage中存的数据取出来给vuex中的state赋值,否则.就说明是第一次打开,则取vuex中定义的state初始值--> <!-- 3.修改代码:1).在App.vue中添加监听事件并把state值存储到sessionStorage;2)修改store/index.js中的state,取出sessionStorage的值看有没有,有就使用,没有就state初始化赋值 --> <h2>登陆账号是:{{$store.getters.getUser.name}}</h2> </div> </template> <script> export default { name:'main' } </script> <style> </style>
3.store/index.js
import Vue from 'vue' import Vuex from 'vuex' // 引入模块user // import user from './modules/user' Vue.use(Vuex) // 公共state对象,存储所有组件的状态 // 判断sessionStorage有没有存储state的值,有就给state赋值,没有就赋初始值 const state =window.sessionStorage.getItem('state') != null?JSON.parse(window.sessionStorage.getItem('state')): { user: { name: '' } } // 唯一取值的方法,类似计算属性 const getters = { getUser(state) { return state.user } } // 唯一可以修改state值的方法,同步阻塞 const mutations = { updateUser(state,user){ state.user = user } } // 异步调用mutation方法,commit const actions = { asyncUpdateUser(context,user){ context.commit('updateUser',user) } } const modules = { } export default new Vuex.Store({ // // 公共state对象,存储所有组件的状态 // // state: { // // user: { // // name: '' // // } // // }, // // 唯一取值的方法,类似计算属性 // // getters:{ // // getUser(state) { // // return state.user // // } // // }, // // 唯一可以修改state值的方法,同步阻塞 // // mutations: { // // updateUser(state,user){ // // state.user = user // // } // // }, // // 异步调用mutation方法,commit // // actions: { // // asyncUpdateUser(context,user){ // // context.commit('updateUser',user) // // } // // }, // // modules: { // // } state, getters, mutations, actions, modules }) // 注册模块化 // export default new Vuex.Store({ // modules:{ // user // } // })
4.store/modules/user.js----模块化模式
const user = { // 公共state对象,存储所有组件的状态 // 判断sessionStorage有没有存储state的值,有就给state赋值,没有就赋初始值 state: window.sessionStorage.getItem('state') != null?JSON.parse(window.sessionStorage.getItem('state')): { user: { name: '' } }, // 唯一取值的方法,类似计算属性 getters:{ getUser(state) { return state.user } }, // 唯一可以修改state值的方法,同步阻塞 mutations : { updateUser(state,user){ state.user = user } }, // 异步调用mutation方法,commit actions : { asyncUpdateUser(context,user){ context.commit('updateUser',user) } } } export default user
5.src/router/index.js ----- 配置路由
import Vue from 'vue' import VueRouter from 'vue-router' import Index from '../views/Index.vue' import main from '../views/main.vue' Vue.use(VueRouter) const routes = [ { path: '/', name: 'Index', component: Index }, { path: '/main', name: 'main', component:main } ] const router = new VueRouter({ routes }) export default router
6.src/App.vue ---- 主页面
<template> <div id="app"> <router-view/> </div> </template> <script> export default { name:'App', mounted(){ // 监听页面是否刷新,一旦刷新,调用方法,存储数据 window.addEventListener('unload',this.saveState) }, methods:{ saveState(){ // 将state数据存储到sessionStorage中 // 模块化时使用 // sessionStorage.setItem('state',JSON.stringify(this.$store.state.user)) // 不使用模块化时使用 sessionStorage.setItem('state',JSON.stringify(this.$store.state)) } } } </script> <style lang="less"> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; } </style>
import Vue from 'vue' import App from './App.vue' import router from './router' import Vuex from 'vuex' import store from './store' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css'; Vue.config.productionTip = false Vue.use(ElementUI) Vue.use(Vuex) new Vue({ router, store, render: h => h(App) }).$mount('#app')