Vuex实例之登录退出

本节使用 Vuex 实现登录和退出功能。输入用户名和密码后,修改 Vuex 中的状态并使用 localStorage 本地存储实现数据持久化,登录成功之后即可实现退出功能。

vue-cli创建项目站点

使用 vue-cli 创建项目,新建文件夹 myvuex 作为项目站点,打开站点,按住 Shift 键的同时右击,在弹出的快捷菜单中选择 “在此处打开命令窗口” 命令,如图 10-2 所示。

image 2025 02 11 19 18 06 259
Figure 1. 图10-2 在命令窗口快速打开站点

在命令窗口中执行 “Vue init webpack vuexlogin”,选择配置安装即可。

在 components 文件夹下新建 login 组件,如图 10-3 所示。

image 2025 02 11 19 18 41 655
Figure 2. 图10-3 新增login.vue

增加路由匹配规则,当访问 /login 时加载 login.vue 组件,路由代码如下。

import Vue from 'vue';
import Router from 'vue-router';
import HelloWorld from '@/components/HelloWorld';
import login from '@/components/login';

Vue.use(Router);

export default new Router({
  routes: [
    {
      path: '/login',
      name: 'login',
      component: login
    },
  ]
});

访问 /login,最终结果如图 10-4 所示。

image 2025 02 11 19 20 02 402
Figure 3. 图10-4 login.vue前端展示

Vuex修改登录状态

操作步骤如下。

  • 安装 Vuex,在终端中执行 “npm install vuex -S”。

  • 在 store 文件夹下新建 index.js,如图 10-5 所示。

image 2025 02 11 19 20 45 322
Figure 4. 图10-5 在store文件夹新增Vuex代码文件

index.js 代码如下。

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    // 0 表示未登录
    // 1 表示已登录
    islogin: 0
  }
});

export default store;

代码解析如下。

在 state 中新增 islogin 属性,属性值为 0 表示用户未登录,属性值为 1 表示用户已登录,默认值为 0。

(3)打开 main.js,在 Vue 实例中引用 Vuex,代码如下。

import Vue from 'vue';
import App from './App.vue'; // 明确指定文件后缀
import router from './router';
// 1. 引用 Vuex
import store from './store';

Vue.config.productionTip = false;

new Vue({
  el: '#app',
  router,
  store, // 2. 挂载 Vuex
  components: { App },
  template: '<App/>'
});

当 Vuex 挂载到 Vue 实例后,就可以在任何页面调用 Vuex 中的数据了。

(4)创建doLogin登录表单组件,如图10-6所示。

image 2025 02 11 19 23 00 984
Figure 5. 图10-6 doLogin.vue登录表单组件

修改路由匹配规则,访问 /doLogin 时展示 doLogin 组件,代码如下。

import Vue from 'vue';
import Router from 'vue-router';
import doLogin from '@/components/doLogin';

Vue.use(Router);

export default new Router({
  routes: [
    {
      path: '/doLogin',
      name: 'doLogin',
      component: doLogin
    }
  ]
});

(5)布局doLogin登录表单组件,代码如下。

视图层代码如下。

<template>
  <div>
    <h1>{{ $store.state.islogin }}</h1>
    <h1>
      <input type="text" placeholder="请输入用户名" v-model="username" />
    </h1>
    <h1>
      <input type="text" placeholder="请输入密码" v-model="password" />
    </h1>
    <button @click="login">登录</button>
  </div>
</template>

代码解析如下。

首先使用 {{$store.state.islogin}} 调用 Vuex 中的 islogin,然后使用 v-model 双向数据绑定获取用户输入的用户名和密码,最后新增登录事件。

运行程序,登录表单组件的效果如图 10-7 所示,0 表示 Vuex 中的 islogin 的值。

image 2025 02 11 19 25 33 301
Figure 6. 图10-7 登录表单组件效果

JS 逻辑代码如下。

export default {
  data() {
    return {
      username: null, // admin
      password: null // 123456
    };
  },
  methods: {
    login() {
      if (this.username == 'admin' && this.password == '123456') {
        // 用户名和密码正确,修改 state 中的 islogin
        // 方法 1:不使用辅助函数
        // ...
      } else {
        console.log('用户名或密码错误');
      }
    }
  }
};

分析:在data中定义username和password,接收用户输入的用户名和密码,在methods中定义login()方法,修改Vuex中的登录状态。

代码解析如下。

在login()方法中判断用户名是否为admin、密码是否为123456。当用户输入正确,修改state中islogin的值,当前并没有在Vuex中定义方法,接下来打开store文件夹下的index.js文件。

(6)在mutations中修改登录状态。

不能直接修改 state 中的值,而是要借助 mutations,修改代码如下。

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    // 0 表示未登录
    // 1 表示已登录
    islogin: 0
  },
  mutations: {
    // 不能直接修改 islogin 的值,需要借助 mutations
    dologin(state) {
      state.islogin = 1;
    }
  }
});

export default store;

返回 doLogin 页面,当用户名和密码输入正确时,调用 mutations 中的 doligin 方法修改登录状态,代码如下。

methods: {
  login() {
    if (this.username == 'admin' && this.password == '123456') {
      // 用户名和密码正确,修改 state 中的 islogin
      // 方法 1:不使用辅助函数
      this.$store.commit('dologin');
    } else {
      console.log('用户名或密码错误');
    }
  }
}

代码解析如下。

在登录组件中调用 mutations 中的方法有两种形式,第一种方法是使用 this.$store.commit('dologin') 直接调用,第二种方法是借助辅助函数调用。

mutations 辅助函数代码如下。

methods: {
    login() {
      if (this.username == 'admin' && this.password == '123456') {
     //用户名和密码正确,修改state中的islogin
     //方法1:不使用辅助函数
     this.$store.commit('dologin')
      } else {
        console.log('用户名或密码错误');
      }
    }
}

代码解析如下。

在登录组件中调用 mutations 中的方法有两种形式,第一种方法是使用 this.$store.commit('dologin') 直接调用,第二种方法是借助辅助函数调用。

mutations 辅助函数代码如下。

import { mapMutations } from 'vuex';

export default {
  data() {
    return {
      username: null, // admin
      password: null // 123456
    };
  },
  methods: {
    ...mapMutations(['dologin']),
    login() {
      if (this.username == 'admin' && this.password == '123456') {
        // 方法二:使用辅助函数
        this.dologin();
      } else {
        console.log('用户名或密码错误');
      }
    }
  }
};

(7)退出登录。

当用户名和密码输入正确时,应显示用户名并有 “退出” 按钮,如图 10-8 所示。

image 2025 02 11 19 34 01 069
Figure 7. 图10-8 登录成功状态显示

在此页面需要实现两个功能,第一个功能为登录成功后显示用户名,第二个功能为用户退出操作。

①显示用户名。

代码如下。

<template>
  <div>
    <h1 v-if="$store.state.islogin == 1">
      用户:admin
      <button @click="logout">退出</button>
    </h1>
    <h1 v-else>
      <router-link to="/doLogin" tag="span">登录</router-link>
    </h1>
  </div>
</template>

代码解析如下。

使用 v-if 进行登录判断,当 $store.state.islogin 等于 1 说明用户已登录,否则显示登录按钮。

②退出功能。

单击 “退出” 按钮,需要将 state 中的 islogin 属性重新赋值为 0,打开 store 下的 index.js,在 mutations 中添加退出方法,代码如下。

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    // 0 表示未登录
    // 1 表示已登录
    islogin: 0
  },
  mutations: {
    // 不能直接修改 islogin 的值,需要借助 mutations
    dologin(state) {
      state.islogin = 1;
    },
    // 退出方法
    dologout(state) {
      state.islogin = 0;
    }
  }
});

export default store;

代码解析如下。

dologout 为退出方法,在 login 组件单击 “退出” 按钮时调用即可,可直接调用,也可使用辅助函数,调用代码如下。

import { mapMutations } from 'vuex';

export default {
  methods: {
    ...mapMutations(['dologout']),
    logout() {
      this.dologout();
    }
  }
};

代码解析如下。

在 login.vue 组件中,单击 “退出” 按钮调用 logout() 方法,然后在 logout() 方法中调用 Vuex 中的 dologout() 退出方法。

(8)localStorage本地存储,实现数据持久化。

当前虽然已经实现了用户的登录和退出,但是当刷新页面时,state 中的 islogin 会恢复成默认的未登录状态,本节将 state 中的值保存到 localStorage 中,代码如下。

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    // 0 表示未登录
    // 1 表示已登录
    islogin: localStorage.getItem('islogin') || 0 //  初始化时从localStorage取值,若没有则默认为0
  },
  mutations: {
    dologin(state) {
      state.islogin = 1;
      localStorage.setItem('islogin', 1); // 使用本地存储实现数据持久化
    },
    dologout(state) {
      state.islogin = 0;
      localStorage.removeItem('islogin'); // 移除本地存储中的 islogin
    }
  }
});

export default store;

代码解析如下。

以上案例中设置本地存储使用了 localStorage.setItem('islogin',1),第一个参数是自定义属性名,第二个参数是存储值。

获取本地存储使用 localStorage.getItem('islogin'),islogin 为属性名。 移除本地存储使用 localStorage.removeItem('islogin'),islogin 为属性名。