当前位置: 首页 > article >正文

【VUE】vue-router

1. vue-router组件

1.1 路由的嵌套

index.js

import {createRouter, createWebHistory} from 'vue-router'

const router = createRouter({
    history: createWebHistory(import.meta.env.BASE_URL),
    routes: [
        {
            path: '/login',
            name: 'login',
            component: () => import('../views/LoginView.vue')
        },
        {
            path: '/info',
            name: 'info',
            component: () => import('../views/InfoView.vue')
        },
        {
            path: '/admin',
            name: 'admin',
            component: () => import('../views/AdminView.vue'),
            children: [
                {
                    path: "",
                    redirect: {name: "mine"}
                },
                {
                    path: "mine",
                    name: "mine",
                    component: () => import('../views/MineView.vue')
                },
                {
                    path: "order",
                    name: "order",
                    component: () => import('../views/OrderView.vue')
                }
            ]
        }
    ]
})
export default router

App.vue

<template>
  <div class="page-header">
    <div class="container">
      <RouterLink to="/login">登录</RouterLink> |
      <RouterLink to="/info">信息</RouterLink> |
      <RouterLink to="/admin">后台</RouterLink> |
      <RouterLink to="/admin/mine">我的</RouterLink>
    </div>
  </div>
  <div class="container">
    <RouterView/>
  </div>
</template>

<script setup>
</script>

<style scoped>
.page-header {
  height: 48px;
  background-color: cornflowerblue;
  line-height: 48px;
}

.container {
  width: 980px;
  margin: 0 auto;
</style>

AdminView.vue

<template>
  <h1>Admin</h1>
  <router-link to="/admin/mine">我的</router-link> |
  <router-link to="/admin/order">订单</router-link>
  <RouterView/>
</template>

<script setup>
</script>

<style scoped>
</style>

1.2 编程式导航

不使用<router-link>标签实现路由的跳转。
使用js代码实现路由跳转,例如:
InfoView.vue

<template>
  <h1>Info</h1>
</template>

<script setup>
import {useRouter} from "vue-router"

const router = useRouter()
// router.push({path:"/admin/order"})
// router.push({name:"login"})
router.push({name: "login", params: {nid: 100}, query: {page: 100}})
</script>

<style scoped>

</style>

浏览器的后退前进缓存中,有以下区别:
push [A,B,C,D,新页面]
replace [A,B,C,新页面]

案例1:博客+公司官网+xx在线平台

  • 未登录,可以查看某些页面

  • 用户登录,去登录

  • 去查看某些页面

    现象:登录页是在有导航条的前提

App.vue

<template>
  <div class="page-header">
    <div class="container">
      <RouterLink to="/info">信息</RouterLink>
      |
      <RouterLink to="/admin">后台</RouterLink>
      |
      <RouterLink to="/admin/mine">我的</RouterLink>
      <div style="float:right;">
        <RouterLink to="/login">登录</RouterLink>
      </div>
    </div>
  </div>
  <div class="container">
    <RouterView/>
  </div>
</template>

<script setup>

</script>


<style scoped>
body {
  margin: 0;
}

.page-header {
  height: 48px;
  background-color: cornflowerblue;
  line-height: 48px;
}

.page-header a {
  display: inline-block;
  padding: 0 10px;
}

.container {
  width: 980px;
  margin: 0 auto;
}

</style>

LoginView.vue

<template>
  <div class="box">
    <p>
      用户名:
      <input type="text" placeholder="用户名" v-model="msg.username">
    </p>
    <p>
      密码:
      <input type="text" placeholder="密码" v-model="msg.password">
    </p>
    <p>
      <button @click="doLogin">登录</button>
    </p>
  </div>
</template>

<script setup>
import {ref} from "vue";
import {useRouter} from "vue-router";

const msg = ref({
  username: "",
  password: ""
})
const router = useRouter()

const doLogin = function () {
  // 1、获取数据
  console.log(msg.value)
  // 2、发送网络请求
  // 3、跳转到首页
  router.push({name:"info"})
}

</script>

<style scoped>
.box {
  width: 300px;
  margin: 100px auto;
}
</style>

案例2:后台管理

现象:登录页面,无导航条的前提。未登录时,不允许查看系统中有哪些菜单。
index.js

import {createRouter, createWebHistory} from 'vue-router'

const router = createRouter({
    history: createWebHistory(import.meta.env.BASE_URL),
    routes: [
        {
            path: '/login',
            name: 'login',
            component: () => import('../views/LoginView.vue')
        },
        {
            path: '/admin',
            name: 'admin',
            component: () => import('../views/AdminView.vue'),
            children: [
                {
                    path: "",
                    redirect: {name: "mine"}
                },
                {
                    path: "mine",
                    name: "mine",
                    component: () => import('../views/MineView.vue')
                },
                {
                    path: "order",
                    name: "order",
                    component: () => import('../views/OrderView.vue')
                }
            ]
        }
    ]
})

export default router

App.vue

<template>
  <div class="container">
    <RouterView/>
  </div>
</template>

<script setup>
</script>

<style scoped>
body {
  margin: 0;
}
.container {
  width: 980px;
  margin: 0 auto;
}
</style>

LoginView.vue

<template>
  <div class="box">
    <p>
      用户名:
      <input type="text" placeholder="用户名" v-model="msg.username">
    </p>
    <p>
      密码:
      <input type="text" placeholder="密码" v-model="msg.password">
    </p>
    <p>
      <button @click="doLogin">登录</button>
    </p>
  </div>
</template>

<script setup>
import {ref} from "vue";
import {useRouter} from "vue-router";

const msg = ref({
  username: "",
  password: ""
})
const router = useRouter()

const doLogin = function () {
  // 1、获取数据
  console.log(msg.value)
  // 2、发送网络请求
  // 3、跳转到首页
  router.push({name:"mine"})
}
</script>

<style scoped>
.box {
  width: 300px;
  margin: 100px auto;
}
</style>

AdminView.vue

<template>
  <div class="page-header">
    <div class="container">
      <RouterLink to="/admin/mine">我的</RouterLink>
      |
      <RouterLink to="/admin/order">订单</RouterLink>
    </div>
  </div>
  <div class="container">
    <RouterView/>
  </div>
</template>

<script setup>
</script>

<style scoped>
body {
  margin: 0;
}
.page-header {
  height: 48px;
  background-color: cornflowerblue;
  line-height: 48px;
}
.page-header a {
  display: inline-block;
  padding: 0 10px;
}
.container {
  width: 980px;
  margin: 0 auto;
}
</style>

1.3 导航守卫

请求之前,路由之前,进行拦截。
守护着每一个路由。

浏览器的本地存储

  • cookie:有效期+保存
  • localStorage:永久保存
  • sessionStorage:浏览器关闭后自动消失

index.js

import {createRouter, createWebHistory} from 'vue-router'

const router = createRouter({
    history: createWebHistory(import.meta.env.BASE_URL),
    routes: [
        {
            path: '/login',
            name: 'login',
            component: () => import('../views/LoginView.vue')
        },
        {
            path: '/admin',
            name: 'admin',
            component: () => import('../views/AdminView.vue'),
            children: [
                {
                    path: "",
                    redirect: {name: "mine"}
                },
                {
                    path: "mine",
                    name: "mine",
                    component: () => import('../views/MineView.vue')
                },
                {
                    path: "order",
                    name: "order",
                    component: () => import('../views/OrderView.vue')
                }
            ]
        }
    ]
})
router.beforeEach(function (to,from,next) {
    // 1.访问登录页面,不需要登录就可以直接去查看
    if (to.name === "login") {
        next()
        return
    }
    // 2.检查用户登录状态,登录成功,继续往后走next();未登录,跳转至登录页面
    let username = localStorage.getItem("name")
    if (!username){
        next({name:"login"})
        return;
    }
    // 3.登录成功且获取到用户信息,继续向后访问
    next()
})
export default router

LoginView.vue

<template>
  <div class="box">
    <p>
      用户名:
      <input type="text" placeholder="用户名" v-model="msg.username">
    </p>
    <p>
      密码:
      <input type="text" placeholder="密码" v-model="msg.password">
    </p>
    <p>
      <button @click="doLogin">登录</button>
    </p>
  </div>
</template>

<script setup>
import {ref} from "vue";
import {useRouter} from "vue-router";

const msg = ref({
  username: "",
  password: ""
})
const router = useRouter()

const doLogin = function () {
  // 1、获取数据
  console.log(msg.value)
  // 2、发送网络请求
  // 3、本地存储用户信息(登录凭证)
  localStorage.setItem("name", msg.value.username)
  // 3、跳转到首页
  router.push({name:"mine"})
}

</script>

<style scoped>
.box {
  width: 300px;
  margin: 100px auto;
}
</style>

AdminView.vue

<template>
  <div class="page-header">
    <div class="container">
      <RouterLink to="/admin/mine">我的</RouterLink>
      |
      <RouterLink to="/admin/order">订单</RouterLink>
      <div style="float:right;">
        <a @click="doLogout">退出</a>
      </div>
    </div>
  </div>
  <div class="container">
    <RouterView/>
  </div>
</template>

<script setup>
import {useRouter} from "vue-router";

const router = useRouter()
function doLogout() {
  localStorage.clear()
  router.push({name:"login"})
}
</script>

<style scoped>
body {
  margin: 0;
}

.page-header {
  height: 48px;
  background-color: cornflowerblue;
  line-height: 48px;
}

.page-header a {
  display: inline-block;
  padding: 0 10px;
  cursor: pointer;
}

.container {
  width: 980px;
  margin: 0 auto;
}

</style>

http://www.kler.cn/news/324481.html

相关文章:

  • [uni-app]小兔鲜-04推荐+分类+详情
  • CSS 中的overscroll-behavior属性
  • 国产化低功耗低延时广覆盖物联网无线通讯方案_LAKI芯片
  • [数据集][目标检测]辣椒缺陷检测数据集VOC+YOLO格式695张5类别
  • C/C++语言基础--C++面向对象、类、对象概念讲解
  • Qt开发技巧(九)去掉切换按钮,直接传样式文件,字体设置,QImage超强,巧用Qt的全局对象,信号槽断连,低量数据就用sqlite
  • Visual Studio 2022
  • 大功率蓝外光激光模组能使用多长时间?
  • STM32+PWM+DMA驱动WS2812 —— 2024年9月24日
  • 信息安全工程师(23)网络安全体系相关模型
  • H.264编解码介绍
  • 什么是托管安全信息和事件管理 SIEM?
  • STM32嵌入式编程学习到提高:【4】UART串口打印
  • 基于baidu的云函数实现隐藏c2真实地址
  • 企业如何做可视化数据看板
  • 物联网系统中LCD屏主流驱动方案详解
  • 华为vxlan
  • 基于VUE的在线茶叶购物网站的设计与实现后端SpringBoot数据库MySQL
  • 算法竞赛当中离散化算法的初步介绍和简单应用
  • 10_React router6
  • React Native 在 build iOS 的时候如果出现关于 `metro` 的错误
  • My_string 运算符重载,My_stack
  • JavaScript 中的闭包的形成及使用场景
  • 代码随想录_刷题笔记_第三次
  • MySQL 高级 - 第十五章 | MySQL 事务日志
  • 完全二叉树的递归创建思路及代码
  • 1Panel安装部署证书(httpsok.com)
  • matlab入门学习(二)矩阵、字符串、基本语句、函数
  • UART驱动学习一(UART硬件介绍)
  • 泛微E8JDK1.6判断时间在早上8点半到晚上六点半之间的值