Vue 中 vue-router 的使用

发布时间 2023-11-23 15:45:34作者: 误会馋

一、内容:
1.一个路径配置对应一个组件,或一个路径配置对应一个函数(请求),称之为一个路由。
2.SPA(single page web application),只有一个页面的应用程序。
3.路由器 router,是一个 vue 的插件库,专门用来实现 SPA。
4.整个应用只有一个router。
5.数据通过 ajax 请求获取。
6.路由与路由器的关系:路由:一组 key-value;路由器:管理路由。

二、安装:
cd到相应的项目目录
执行命令:npm i vue-router@3 【指定版本3】

三、引入‘路由器插件库’:
在main.js添加:

import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);

四、给路由器配置路由:

在src下创建目录router,在router目录下创建文件index.js,并添加配置:

//用于构建路由器
import VueRouter from "vue-router";

import MyLogin from "../pages/MyLogin";
import User from "../pages/User";
import Manager from "../pages/Manager";

const router = new VueRouter({    
    routes:[
        {
            path:'/',
            component:MyLogin,
            meta: { title: '登录'}
        },{
            name: 'login',
            path:'/login',
            component:MyLogin,
            meta: { title: '登录'}
        },{
            path:'/user',
            component:User,
            meta: { title: '用户', requiresAuth: true, roles: ['User'] }
        },{
            path:'/manager',
            component:Manager,
            meta: { title: '管理员', requiresAuth: true, roles: ['Admin']  }
        }
    ]
});

//路由守卫
router.beforeEach((to,from,next)=>{
    if(to.meta.requiresAuth){ 
     //对特定页面进行路由守卫 let token = localStorage.getItem('token'); if(token == null || token=== ''){ next({name: 'login'}); //localStorage没有token,返回登录页面 } else { let fruit = atob(token.split(".")[1]); let decoded = JSON.parse(fruit); let currentTime = Math.floor(Date.now() / 1000); if (currentTime > decoded.exp) { console.log('令牌已过期!'); next({name: 'login'}); //token 过期,返回登录页面 } else { if (to.meta.roles.includes(decoded.role)) { next(); } else { console.log('无权限访问!'); next({name: 'login'}); //企图访问其他角色才可访问的页面,返回登录页面 } } } } else { next(); } }); router.afterEach((to,from)=>{ document.title = to.meta.title; }); export default router;

五、引入配置好的‘路由器’,并将其交给 vm:

在main.js添加:

import router from './router';

//交给vm,即可全局访问路由器
export default new Vue({
  el:'#app',
  render: h => h(App),
  router 
});

则main.js全文如下:

import Vue from 'vue';
import VueRouter from 'vue-router';
import router from './router';
import App from './App.vue';

Vue.config.productionTip = false;
Vue.use(VueRouter);

//交给vm,即可全局访问路由器
export default new Vue({
  el:'#app',
  render: h => h(App),
  router
});

六、组件中使用:

红色字体部分

<template>
  <!--登录组件-->
  <div class="login-container">
    <div class="login-content">
      <el-form ref="form" :rules="rules" :inline="true" :model="form" label-width="80px" @keyup.enter.native="onSubmit('form')">
        <el-form-item label="用户名:" prop="username">
          <el-input v-model.trim="form.username" placeholder="请输入用户名" style="width:250px;"></el-input>
        </el-form-item>      
        <el-form-item label="密码:" prop="password">
          <el-input placeholder="请输入密码" v-model="form.password" autocomplete="off" show-password style="width:250px;"></el-input>
        </el-form-item>
        <el-form-item label=" ">
          <el-button type="primary" @click="onSubmit('form')" style="width: 170px;">登录</el-button>          
          <el-button @click="reset('form')">重置</el-button>
          <p v-if="error" class="error">{{ error }}</p>
        </el-form-item>
      </el-form>
    </div> 
  </div>
</template>

<script>
import pass from '../utils/pass'; 
import api from '../network/api';
import CryptoJS from 'crypto-js'; 

export default {
  name: 'MyLogin',
  data() {
    return {
      error: '',
      form:{
        username:'',
        password:''
      },
      rules: {
        username: [
            { required: true, message: '请输入用户名', trigger: 'blur' }
          ],
        password:[
            { required: true, message: '请输入密码', trigger: 'blur' }
        ]
      }
    };
  },
  methods: {
    onSubmit(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.login(this.form.username, this.form.password);
        } else {
          console.log('请输入用户名和密码!');
          return false;
        }
      });
    },

    login(username, password){
      const loginmodel = this.encryptPassword(username, password);
      api.login(loginmodel)
      .then(res=>{
       const success = res.status === 200 && res.data && res.data.success
        if(!success){
          let msg = '用户名或密码错误!';
          if(res.data && res.data.message){
            msg = res.data.message;
          }
          this.error = msg;
        } else {
          localStorage.setItem('token',res.data.data);
          if(username==='admin' ){
            this.$router.push('/manager');
          } else {
            this.$router.push('/user');
          } 
        }
      })
      .catch(error=>{
        console.error(error);
      });      
    },
    
    encryptPassword(username, password){
        const hash = CryptoJS.SHA256(password).toString(); //password 以utf-8编码,经SHA 256散列计算,返回散列值的十六进制表示
        return {username:username,password:hash};
    }, 

    reset(){
      this.error = '';
      this.form.username = '';
      this.form.password = '';
      this.$refs['form'].resetFields();  
    },
  }
}
</script>

<style scoped>
.login-container {
  background-image: url('../assets/loginbg.png'); 
  background-position: center;  
  background-repeat: no-repeat;  
  background-size: cover;  
  position: fixed;  
  top: 0;  
  right: 0;  
  bottom: 0;  
  left: 0;  
  z-index: -99;  
}  
  
.login-content {  
  position: relative; 
  width: 400px;
  margin: 250px auto; 
  padding: 20px; 
  background-color: rgba(255, 255, 255, 1);
  opacity: 0.9;
}

.error {  
  color: red;  
  margin-top: 10px;  
} 
</style>