【Vuex】Vue中使用Vuex(模拟登录)

mock一个登录示例

安装mockjs

npm install mockjs --save-dev

首先在mock包下创建两个文件index.js和userList.js

然后在全局main.js中加入

require('../mock')

在index.js中写

// 首先引入Mock
const Mock = require('mockjs');
import userList from './userList'

// 设置拦截ajax请求的相应时间
Mock.setup({
    timeout: '200-600'
});

let configArray = [];

// 使用webpack的require.context()遍历所有mock文件
const files = require.context('.', true, /\.js$/);
files.keys().forEach((key) => {
    if (key === './index.js') return;
    configArray = configArray.concat(files(key).default);
});

// 注册所有的mock服务
configArray.forEach((item) => {
    for (let [path, target] of Object.entries(item)) {
        let protocol = path.split('|');
        Mock.mock(new RegExp('^' + protocol[1]), protocol[0], target);
    }
});

在userList.js中写

import Mock from 'mockjs' //导入mockjs

const userList = {  //定义用户数据
    data: {
        total: 6,

        //前两个用户数据分别固定设为管理员和普通用户,为后续权限设置做准备,其他用户随机生成
        userinfo: [{
            username: 'dza6196172',
            password: '123456',
            roles: 'admin',
            name: '张三',
            age: 23,
            job: '前端工程师',
            token: '000111222333444555666',
            id: '100',
        }, {
            username: '123', 
            password: '123123',
            roles: 'editor',
            name: '测试1',
            'age|20-30': 23,
            job: '前端工程师',
            token: '145145145123123123111',
            id: '101',
        }, {
            username: '@word(3, 5)',
            password: '123456',
            roles: 'editor',
            name: '@cname',
            'age|20-30': 23,
            'job|1': ['前端工程师', '后端工程师', 'UI工程师', '需求工程师'],
            token: '@guid()',
            id: '102',
        }, ],
        meta: {
            status: 200,
            message: 'success',
        }
    },
};

//定义请求方法与路径
export default {
    'get|/user': userList,
}

然后在登录页面找到登录的按钮,绑定下面这个点击事件,进行请求测试

async getuser(){
    const {data:res} = await this.$http.get('/user')
    console.log(res);
}

页面接收到返回数据即测试成功。

测试完可以发送请求以后,在methods中写模拟登录的方法请求,记得要改变按钮的点击事件哦

loginButton(){
        this.$refs.loginForm.validate(async valid => { //规则校验
        let data={
            username:this.loginForm.username,
            password:this.loginForm.password
        }
        if(!valid)return
        const {data:res} = await this.$http.post('/user',data) //发送请求
        console.log(res.data)
        console.log(res.data.userinfo[1].name)
        if(res.data.meta.status!==200){
            return this.$message.error('用户名或密码错误')
        }
        this.$message.success('登录成功')
        this.$router.push('home')
    })
}

然后在mock/index.js中加入代码

Mock.mock('/user', 'post', req => { //路径与请求方式
    const { username, password } = JSON.parse(req.body); //将传递进来的数据保存
    for (let i = 0; i < userList.data.userinfo.length; i++) {
        //判断userList中是否存在该用户并且用户密码是否正确
        if (username === userList.data.userinfo[i].username && password === userList.data.userinfo[i].password) {
            return {
                meta: {
                    msg: 'success',
                    status: 200
                },
                user: {
                    username: userList.data.userinfo[i].username,
                    roles: userList.data.userinfo[i].roles
                }
            }
        }
    }
    return {
        meta: {
            msg: 'error',
            status: 201
        }
    }
})

同时不要忘记将mock/userList.js中的get方法变为post方法

输入对应账号密码,此时mock登录成功。

Vuex的使用

我想登录以后显示用户名,那么在login中就要把用户名保存在vuex中,这样可以实现页面之间的数据传递。

在store包下创建index.js

写入下面代码

import { createStore } from 'vuex'

export default createStore({
  //公共state对象,存储所有组件的状态
  state: {
    user:{
      name:'',
    }
  },
  //唯一取值的方法,计算属性
  getters: {
    getUser(state){
      return state.user;
    }
  },
  //唯一可以修改state值的方法,同步阻塞
  mutations: {
    updateUser(state,user){
      state.user = user;
    }
  },
  //异步调用 mutations方法
  actions: {
    asyncUpdateUser(context,user){
      context.commit('updateUser',user);
    }
  },
  modules: {
  }
})

同时在login.vue中的loginButton方法中加入

//vuex存储当前用户名
this.$store.dispatch('asyncUpdateUser',{name:res.data.userinfo[1].name})

然后在登录跳转后的首页加入下面这段,就可以显示用户名了。

<p>{
    
    {$store.getters.getUser.name}}</p>

但是会出现一个问题,如果刷新页面的话,用户名就会消失。

浏览器刷新时Vuex数据丢失问题

我们把数据传递到下一个页面后,再次刷新后会让store种的数据重置,导致数据丢失。要让 Vuex 中数据持久化存储,这样刷新页面时 store 中的存储的数据能够保证不会丢失。

解决过程

监听页面是否剧新,如果页面剧新了,将 state对象存入到 sessionStorage中。页面打开之后,判断sessionStorage 中是否存在 state对象,如果存在,则说明页面是被刷新过的,将sessionStorage 中存的数据取出来给vuex中的 state赋值。如果不存在,说明是第一次打开,则取vuex中定义的 state初始值。

注意:我们要将传递数据保存到sessionStorage中,要知道sessionStorage中只能存储字符串,所以先转换再存储。

在app.vue中写

mounted() {
  window.addEventListener('unload', this.saveState)
},
methods: {
  saveState() {
    sessionStorage.setItem('state', JSON.stringify(this.$store.state))
  },
},

在store/index.js中,给state添加判断条件:

//公共state对象,存储所有组件的状态
  state:sessionStorage.getItem('state') ? JSON.parse(sessionStorage.getItem('state')): {
    user:{
      name:'',
    }
  },

再次测试,刷新以后用户名不会消失。

参考资料:

https://blog.csdn.net/iufesjgc/article/details/108665553

https://www.bilibili.com/video/BV1cU4y1j7aP?p=1&vd_source=6264a75f147feaf5cd9f6d06ff0ba040

猜你喜欢

转载自blog.csdn.net/m0_62811051/article/details/129647949