IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> Vue+SpringBoot项目练习(五:Vuex前端路由拦截器) -> 正文阅读

[JavaScript知识库]Vue+SpringBoot项目练习(五:Vuex前端路由拦截器)

完成element的引入设计完成Login.vue页面后就该通过使用vuex前端路由来进行登录拦截

一、前端路由

在第二篇中曾说过#号是使用Hash的模式,我们可以通过相关配置来去掉
这里#号称为锚点这里可以使得URL 发生了变化,但页面不会跳转。
这个办法可以缓解后端服务器的压力,利用Ajax可以不重载页面就刷新数据,加上#号的特性------改变URL不请求后端,可以实现前端页面的整体变化而不去请求后端

#号后面的地址称为Hash

另一种方式为History模式,这种方式使用了History API—这种模式是很对历史记录的Api,原理是把这个页面保存在一个对象里(state),当页面的URL变化找到对象的对象,然后还原这个页面

History解决#号实现前端路由

二、使用History模式

从默认的 Hash模式切换为 History 模式只需修改路由配置即可。在 src\router.js加入mode: 'history'即可如图所示
在这里插入图片描述
运行项目,访问不加#号的 http://localhost:8080/login ,成功加载页面。
在这里插入图片描述

三、Vuex与前端登录拦截器

练习项目为前后端分离项目所以这次不使用后端拦截
实现前端登录器,需要在前端判断用户的登录状态

实现方式:

  • 在组件中的data中设置一个状态标志
  • 通过全局属性来Vuex实现

1、引入Vuex

在项目文件夹中运行npm install vuex --save,在src目录下创建一个文件夹并创建store文件夹,并创建index.js------src\store\index.js来进行vue和vuex的使用如图所示
在这里插入图片描述
在 index.js 里设置我们需要的状态变量和方法。为了实现登录拦截器,我们需要一个记录用户信息的变量。为了方便日后的扩展(权限认证等),我们使用一个用户对象而不是仅仅使用一个布尔变量。同时,设置一个方法,触发这个方法时可以为我们的用户对象赋值。完整的代码如下:

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

Vue.use(Vuex)

export default new Vuex.Store({
    /*
    * localStorage本地存储
    * 在项目打开的时候会判断本地存储中是否有 user 这个对象存在,
    * 如果存在就取出来并获得 username 的值,否则则把 username 设置为空。
    * 这样我们只要不清除缓存,登录的状态就会一直保存。
    */
    state: {
        user: {
            username: window.localStorage.getItem('user' || '[]') == null ? '' : JSON.parse(window.localStorage.getItem('user' || '[]')).username
        }
    },
    mutations: {
        login (state, user) {
            state.user = user
            window.localStorage.setItem('user', JSON.stringify(user))
        }
    }
})

2、修改路由配置

区分页面是否拦截,需要修改src\router.js,在需要拦截的路由中加一个数据设置一个requireAuth属性
requireAuth属性作用是表明该路由是否需要登录验证,在进行全局拦截时,我们将通过该属性判断路由的跳转,该属性包含在meta属性中:
在这里插入图片描述
完整的index.js代码如下

import Vue from "vue";
import Router from "vue-router";


import AppIndex from "@/views/AppIndex";
import Login from "@/views/Login";
Vue.use(Router);

export default new Router({
    routes: [
        {
            path: "/login",
            component:Login
        },
        {
            path: "/index",
            component: AppIndex,
            meta:{
                requireAuth: true
            }
        }
    ]
});


3、使用钩子函数判断是否拦截

钩子函数及在某些时机会被调用的函数。这里我们使用 router.beforeEach(),意思是在访问每一个路由前调用。
打开src\main.js ,首先添加对store 的引用

import store from './store'

并修改Vue对象内容

new Vue({
  components:{App},
  router,
  store,
  render: h => h(App),
}).$mount('#app')

接着写 beforeEach() 函数

router.beforeEach((to, from, next) => {
      if (to.meta.requireAuth) {
        if (store.state.user.username) {
          next()
        } else {
          next({
            path: 'login',
            query: {redirect: to.fullPath}
          })
        }
      } else {
        next()
      }
    }
)

l逻辑如下:
1、首先判断访问的路径是否需要登录
2、如果需要判断Store里有没有存储user的信息,存在即放行并存储访问的页面路径(方便以后跳转)

完整的main.js代码

import Vue from 'vue'
import App from './App.vue'
import router from "./router"
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import store from './store'
var axios = require('axios')
axios.defaults.baseURL = 'http://localhost:8888/api'

Vue.prototype.$axios = axios
Vue.config.productionTip = false
Vue.use(ElementUI)

router.beforeEach((to, from, next) => {
      if (to.meta.requireAuth) {
        if (store.state.user.username) {
          next()
        } else {
          next({
            path: 'login',
            query: {redirect: to.fullPath}
          })
        }
      } else {
        next()
      }
    }
)


new Vue({
  components:{App},
  router,
  store,
  render: h => h(App),
}).$mount('#app')

4、修改Login.vue

之前的登录组件中,我们只是判断后端返回的状态码,如果是 200,就重定向到首页。在经过前面的配置后,我们需要修改一下登录逻辑,以最终实现登录拦截。

逻辑如下:
1、点击登录按钮,向后端放松数据
2、受到后端返回的成功代码时,触发 store 中的login() 方法,把 loginForm 对象传递给 store 中的user 对象**(简单实现)**

修改后的login()方法

  login () {
      var _this = this
      console.log(this.$store.state)
      this.$axios
          .post('/login', {
            username: this.loginForm.username,
            password: this.loginForm.password
          })
          .then(successResponse => {
            if (successResponse.data.code === 200) {
              // var data = this.loginForm
              _this.$store.commit('login', _this.loginForm)
              var path = this.$route.query.redirect
              this.$router.replace({path: path === '/' || path === undefined ? '/index' : path})
            }
          })
          // eslint-disable-next-line no-unused-vars
          .catch(failResponse => {
          })
    }
  }

完整Login.vue代码

<template>
  <body id="poster">
    <el-form class="login-container" label-position="left"
             label-width="0px">
      <h3 class="login_title">系统登录</h3>
      <el-form-item>
        <el-input type="text" v-model="loginForm.username"
                  auto-complete="off" placeholder="账号"></el-input>
      </el-form-item>
      <el-form-item>
        <el-input type="password" v-model="loginForm.password"
                  auto-complete="off" placeholder="密码"></el-input>
      </el-form-item>
      <el-form-item style="width: 100%">
        <el-button type="primary" style="width: 100%;background: #505458;border: none" v-on:click="login">登录</el-button>
      </el-form-item>
    </el-form>
  </body>
</template>

<script>
export default {
  name: "Login",
  data () {
    return {
      loginForm: {
        username: '',
        password: ''
      },
      responseResult: []
    }
  },
  methods: {
  login () {
//     this.$axios
//         .post('/login', {
//           username: this.loginForm.username,
//           password: this.loginForm.password
//         })
//         .then(successResponse => {
//           if (successResponse.data.code === 200) {
//             this.$router.replace({path: '/index'})
//           }
//         })
//         // eslint-disable-next-line no-unused-vars
//         .catch(failResponse => {
//         })
//   }
// }
      var _this = this
      console.log(this.$store.state)
      this.$axios
          .post('/login', {
            username: this.loginForm.username,
            password: this.loginForm.password
          })
          .then(successResponse => {
            if (successResponse.data.code === 200) {
              // var data = this.loginForm
              _this.$store.commit('login', _this.loginForm)
              var path = this.$route.query.redirect
              this.$router.replace({path: path === '/' || path === undefined ? '/index' : path})
            }
          })
          // eslint-disable-next-line no-unused-vars
          .catch(failResponse => {
          })
    }
  }

}
</script>

<style>
  #poster{
    background:url("../assets/login.jpg") no-repeat;
    background-position: center;
    height: 100%;
    width: 100%;
    background-size: cover;
    position: fixed;
  }
  body{
    margin: 0px;
  }

  .login-container {
    border-radius: 15px;
    background-clip: padding-box;
    margin: 90px auto;
    width: 350px;
    padding: 35px 35px 15px 35px;
    background: #fff;
    border: 1px solid #eaeaea;
    box-shadow: 0 0 25px #cac6c6;
  }

  .login_title {
    margin: 0px auto 40px auto;
    text-align: center;
    color: #505458;
  }



</style>


5、检验效果

运行前端项目,访问http://localhost:8080/#/index后页面直接拦截跳转
http://localhost:8080/#/login?redirect=%2Findex如果所示
在这里插入图片描述

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-24 07:51:19  更:2021-11-24 07:53:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 4:48:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码