vue登录配合路由前置守卫小dome(vue-router配合vuex实现案例)

首先准备

  1. 下载好vue-router和vuex,基本的路由和数据状态
  2. npm i vue-router --save
  3. npm i vuex --save

router/index.js代码如下

import Vue from 'vue'
import Router from 'vue-router'
//引入vuex仓库在路由器安置守卫进行判断使用
import store from '../vuex/index'
Vue.use(Router)

const route = new Router({
    
    
  routes: [{
    
    
    path: "/login",
    component: () => import('../components/login/login.vue')
  },
  {
    
    
    path: '/',
    component: () => import('../components/views/home'),
    children: [{
    
    
      path: "vuexzhuangtaiguanli",//Vuex状态管理解释
      component: () => import('../components/pagescom/vuexzhuangtaiguanli.vue')
    }]
  }
  ]
})
//每一个路由跳转之前都会走前置方法
route.beforeEach((to, from, next) => {
    
    
//to表示要去的路由的信息
//from表示来自哪个路由的信息
//next 执行next()继续走路由  next('/xxx')跳转到具体路由
  console.log(store,'storestore')
  //要去的路由是否为/login 不是往下走  是的话直接进
  if (to.fullPath != '/login') {
    
    
    //要进的页面不是登录页面
    //判断 账号名  为空整明未登录 判断状态管理里面username的值 有值代表登录 让路由跳转刀对应页面
    if (store.state.username != '') {
    
    
      //不为空跳转
      console.log('不为空跳转')
      next()
    } else{
    
    
      //账号等于空  说明没登陆 还让他留在登录页面 或者想通过路由直接跳转刀对应页面 由于没有username  也直接到了login页面
      console.log(store.state.username,'账号等于空',store.state.username)
      next('/login')
    }
  } else {
    
    
    //是登录页面
    console.log('是登录页面')
    next()
  }

})
export default route

store/index.js代码如下

import Vuex from 'vuex'
import Vue from 'vue'
//vuex-persistedstate模块是用来持久化vuex中的数据,不至于刷新页面数据丢失
import persistedstate from 'vuex-persistedstate'
Vue.use(Vuex)
const store = new Vuex.Store({
    
    
  plugins:[persistedstate()],
  state: {
    
    
    username: '',
    password:"",
    num:0
  },
  getters: {
    
    
  //返回密码
    getterusernameandpassword(state){
    
    
      return state.username+state.password
    }
  },
  mutations: {
    
    
  //num自增
    usernameAsyn(state,num){
    
    
      state.num+=num;
      console.log(state.num)

    },
    //改变vuex中账号和密码的值
    getUsernameAndPassword(state,obj){
    
    
            state.username=obj.username;
            state.password=obj.password;
            console.log(state)
    },
    //账号制空
    regUsername(state){
    
    
      state.username=''
    }
  },
  actions: {
    
    
  
  }
})
export default store

在main中引入两个index.js

import Vue from 'vue'
import App from './App'
import './assets/css/reset.css'
import './assets/js/rem'
//引入elm ui 及其样式css
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
//引入router store 
import router from './router'
import store from './vuex/index' 
Vue.config.productionTip = false
//引入echarts
import echarts from 'echarts'
//挂载到原型上
Vue.prototype.$echarts = echarts
/* eslint-disable no-new */
new Vue({
    
    
  el: '#app',
  router,
  store,
  components: {
    
     App },
  template: '<App/>'
})

两个页面分别为login.vue和vuexzhuangtaiguanli.vue,
这里其实只是用到页面的header.vue(页面头部组件),由于本人审美能力不太行 我就不加图了哈哈哈
在login.vue中代码为

<template >
  <div class="container">
    <el-form :model="ruleForm" status-icon ref="ruleForm" label-width="100px" class="demo-ruleForm">
      <el-form-item label="账号">
        <el-input v-model.number="ruleForm.username"></el-input>
      </el-form-item>
      <el-form-item label="密码">
        <el-input type="password" v-model="ruleForm.password" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click.13="LoginSubmit">登录</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
export default {
    
    
  data() {
    
    
    return {
    
    
      ruleForm: {
    
    
        password: "",
        username: ""
      }
    };
  },
  methods: {
    
    
    LoginSubmit() {
    
    
    //判断是否为空
      if (this.ruleForm.password != "" && this.ruleForm.username != "") {
    
    
      //使用模拟数据进行登录
        if (
          this.ruleForm.password == "666666" &&
          this.ruleForm.username == "zjq"
        ) {
    
    
          this.$alert("登陆成功");
          let obj = {
    
    
            password: this.ruleForm.password,
            username: this.ruleForm.username
          };
          //改变vuex中username和password的值
          //同步方法使用commit触发
          //第一个参数为方法名,第二个参数为要传送的值,这里传送的是对象
          this.$store.commit("getUsernameAndPassword", obj);
          console.log(this.$store.state,'this.$store.state');
           //状态存储完成后,会会经过路由前置守卫在router/index中进行判断,随后路由跳转
          this.$router.push("/vuexzhuangtaiguanli");
        } else {
    
    
          this.$alert("账号或密码错误");
        }
      } else {
    
    
        this.$alert("账号或密码不能为空");
      }
    }
  }
};
</script>
<style  scoped>
.container {
    
    
  width: 500px;
  height: 500px;
  margin: 200px auto;
}
</style>

header.vue 代码 主要是vuex方法的反显

<template >
  <div class="container">
    <p>当前账号是:{
    
    {
    
    username}}</p>
    <!-- <p>{
    
    {
    
    getterusernameandpassword}}</p> -->
    <span @click="goLogin">退出</span>
    <!-- <p>{
    
    {
    
    password}}</p> -->
    <p @click="usernameAsyn(6)">点击改变vuex中的num</p>
  </div>
</template>
<script>
//这里只使用了mapGetters, mapState,mapMutations  action类似 卸载methhods中
import {
    
     mapGetters, mapState,mapMutations } from "vuex";
export default {
    
    
  data() {
    
    
    return {
    
    };
  },
  computed: {
    
    
  //获取vuex中的getters和state 使用mapXXX可以直接写道computed中,state中的变量名和getters中的方法名可以直接作为本组件的变量使用
    ...mapState(['username']),
    // ...mapState(['password']),
    // ...mapGetters(["getterusernameandpassword"])
  },
  methods: {
    
    
  //同步方法mapMutations 里面的方法可以在页面直接作为方法直接调用
    ...mapMutations(['usernameAsyn']),
    //退出方法
    goLogin() {
    
    
    //同步方法使用commit调用
    //异步方法使用dispatcher调用 (当前页面没使用)
      this.$store.commit("regUsername");//清除了vuex中的username的数据值
      this.$router.push("/login");
    }
  },
  mounted() {
    
    }
};
</script>
<style  scoped>
.container {
    
    
  font-weight: 800;
  font-size: 0.35rem;
}
p {
    
    
  font-size: 0.25rem;
  font-weight: bold;
  display: inline-block;
  width: 200px;
}

span {
    
    
  font-size: 0.25rem;
  float: right;
  width: 200px;
}
</style>

猜你喜欢

转载自blog.csdn.net/qq_43291759/article/details/109358365