Vue3.3指北(四)

news2024/11/28 4:48:18

Vue3.3指北

  • 1、WebPack - VueCLI
    • 1.1、WebPack安装VueCli
    • 1.2、vue create 创建项目
    • 1.3、项目目录结构介绍
  • 2、Vite+Vue3
    • 2.1、认识create-vue
    • 2.2、使用create-vue创建项目
    • 2.3、项目目录剖析
    • 2.4、ESlint代码规范及手动修复
    • 2.5、通过eslint插件来实现自动修正
  • 3、VueRouter4
    • 3.1、单页应用程序介绍
    • 3.2、前端路由和后端路由
    • 3.3、前端路由模式
      • 3.3.1、hash模式
      • 3.3.2、history 模式
  • 4、VueRouter的使用
    • 4.1、声明路由匹配规则
    • 4.2、不同的历史记录模式
    • 4.3、`<router-link>`补充
      • 4.3.1、样式高亮
      • 4.3.2、自定义类名
    • 4.4、组件的存放目录
    • 4.5、Vue-router的常见用法
      • 4.5.1、路由重定向
      • 4.5.2、404
      • 4.5.3、路由的懒加载
      • 4.5.4、动态路由
  • 5、编程式导航和声明式导航
    • 5.0、命名路由
    • 5.1、编程式导航API
      • 5.1.1、$router.push
        • 1、path跳转方式
        • 2、path路径跳转传参(query传参)
        • 4、name命名路由跳转
        • 5、name命名路由跳转传参 (query传参)
        • 6、name命名路由跳转传参 (动态路由传参)
      • 5.1.2、$router.replace
      • 5.1.3、$router.go(n)
    • 5.2、声明式导航
      • 5.2.1、跳转传参
        • 1、查询参数传参
        • 2、动态路由传参
    • 5.2.2、使用props接收路由参数
  • 6、 router和route的区别
  • 7、嵌套路由
    • 7.1、一级路由
    • 7.2、二级路由
  • 8、导航守卫
    • 8.1、全局前置守卫
      • 8.1.1、示例
      • 8.1.2、路由元信息
      • 8.1.2、next函数的三种调用方式
    • 8.2、全局后置守卫
    • 8.3、keep-alive缓存组件
      • 8.3.1、keep-alive的三个属性
      • 8.1.2、next函数的三种调用方式
    • 8.2、全局后置守卫
    • 8.3、keep-alive缓存组件
      • 8.3.1、keep-alive的三个属性

视频参考教程: 2021年Vue3.0全家桶全系列精讲
随笔记源码: 逍遥的人儿 / KuangStudyVue3
在这里插入图片描述

1、WebPack - VueCLI

  • 官网:安装 | Vue CLI (vuejs.org)

1.1、WebPack安装VueCli

  1. 全局安装 Vue_CLI
npm install -g @vue/cli
  1. 查看 Vue_CLI 版本
# 查看 Vue_CLI 版本
vue --version

# 升级 Vue_CLI 到最新版
npm update -g @vue/cli

1.2、vue create 创建项目

  1. 在空目录下创建新项目
vue create hello-vuecli
  1. 会被提示选取一个 preset 预设

在这里插入图片描述

Vue CLI v5.0.8
? Please pick a preset: (Use arrow keys)
> Default ([Vue 3] babel, eslint)
  Default ([Vue 2] babel, eslint)
  Manually select features
  • Default:默认勾选 babel、eslint 的Vue3/Vue2,回车之后直接进入装包
  • manually:自定义勾选特性配置,选择完毕之后,才会进入装包

默认的设置非常适合快速创建一个新项目的原型,而手动设置则提供了更多的选项。

在这里插入图片描述

? Please pick a preset: Manually select features
? Check the features needed for your project: (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed)
 (*) Babel
 ( ) TypeScript
 ( ) Progressive Web App (PWA) Support
 (*) Router
 (*) Vuex
>(*) CSS Pre-processors
 (*) Linter / Formatter
 ( ) Unit Testing
 ( ) E2E Testing

分别选择:

  • Babel:es6 转 es5
  • Router:路由
  • Vuex:数据容器,存储共享数据
  • CSS Pre-processors:CSS 预处理器,后面会提示你选择 less、sass、stylus 等
  • Linter / Formatter:代码格式校验

介绍下所有选项的作用:

选项描述
Babelvue项目中普遍使用es6语法,但有时我们的项目需要兼容低版本浏览器,这时就需要引入babel插件,将es6转成es5
TypeScriptTypeScript通过添加类型来扩展JavaScript。通过了解JavaScript,TypeScript可以节省您捕获错误的时间并在运行代码之前提供修复。任何浏览器,任何操作系统,任何运行JavaScript的地方。
Progressive Web App (PWA) Support渐进式Web应用程序(PWA)支持
Router路由
VuexVuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化
CSS Pre-processorsCSS预处理器
Linter / Formatter格式化程序
Unit Testing单元测试
E2E Testing端到端(end-to-end)

接着选择Vue的版本:

? Choose a version of Vue.js that you want to start the project with (Use arrow keys)
> 3.x
  2.x

接着选择是否使用 history 路由模式,这种模式兼容不好,所以这里输入 n 不使用

? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n)

选择 CSS 预处理器,这里选择我们熟悉的 Less

? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default):
  Sass/SCSS (with dart-sass)
> Less
  Stylus

选择校验工具,这里选择 ESLint + Standard config 标准化

? Pick a linter / formatter config:
  ESLint with error prevention only
  ESLint + Airbnb config
> ESLint + Standard config
  ESLint + Prettier

选择在什么时机下触发代码格式校验:

  • Lint on save:每当保存文件的时候
  • Lint and fix on commit:每当执行 git commit 提交的时候
  • 这里建议两个都选上,更严谨
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed)
 (*) Lint on save
>(*) Lint and fix on commit (requires Git)

Babel、ESLint 等工具会有一些额外的配置文件,这里的意思是问你将这些工具相关的配置文件写到哪里:

  • In dedicated config files:分别保存到单独的配置文件
  • In package.json:保存到 package.json 文件中
  • 这里建议选择第 1 个,保存到单独的配置文件,这样方便我们做自定义配置
? Where do you prefer placing config for Babel, ESLint, etc.?
> In dedicated config files
  In package.json

这里里是问你是否需要将刚才选择的一系列配置保存起来,然后它可以帮你记住上面的一系列选择,以便下次直接重用。这里根据自己需要输入 y 或者 n,我这里输入 n 不需要。

Save this as a preset for future projects? (y/N)

安装成功后,根据命令行的提示命令输入,来启动项目

在这里插入图片描述

在这里插入图片描述

1.3、项目目录结构介绍

├── node_modules              第三方包存储目录
├── public                    任何放置在 public 文件夹的静态资源都会被简单的复制,而不经过 webpack。
│   ├── favicon.ico           浏览器收藏夹图标
│   └── index.html            单页面 HTML 文件
├── src
│   ├── assets                公共资源目录,放图片等资源
│   ├── components            公共组件目录
│   ├── router                Vue Router 路由模块
│   ├── store                 Vue 容器模块
│   ├── views                 视图组件存储目录,所有的路由页面都存储到这里
│   ├── App.vue               根组件,最终被替换渲染到 index.html 页面中 #app 入口节点
│   └── main.js               整个项目的启动入口模块
├── .browserslistrc           指定了项目的目标浏览器的范围。这个值会被 @babel/preset-env 和 Autoprefixer 用来确定需要转译的 JavaScript 特性和需要添加的 CSS 浏览器前缀
├── .editorconfig             EditorConfig 帮助开发人员定义和维护跨编辑器(或IDE)的统一的代码风格,详情参考这里:https://editorconfig.org/。
├── .eslintrc.js              ESLint 的配置文件
├── .gitignore                Git 的忽略配置文件,告诉Git项目中要忽略的文件或文件夹
├── README.md                 说明文档
├── babel.config.js           Babel 的配置文件
├── package-lock.json         记录安装时的包的版本号,以保证自己或其他人在 npm install 时大家的依赖能保证一致
└── package.json              包说明文件,记录了项目中使用到的第三方包依赖信息等内容

在这里插入图片描述

2、Vite+Vue3

  • 与 Vue CLI 类似,Vite 也是一个提供基本项目脚手架和开发服务器的构建工具。
  • Vite 并不是基于 Webpack 的,它有自己的开发服务器,速度更快
    • Vite 先启动服务,按需加载
    • Webpack 则是先全部打包 再启动服务

2.1、认识create-vue

  • create-vue是Vue官方新的脚手架工具,底层切换到了 vite (下一代前端工具链),为开发提供极速响应

在这里插入图片描述

2.2、使用create-vue创建项目

前置条件 - 已安装16.0或更高版本的Node.js

  • 执行如下命令,这一指令将会安装并执行 create-vue
npm create vite@latest

在这里插入图片描述

根据提示运行指令,【第一次体验Vite,构建速度真的好快啊我靠

在这里插入图片描述

2.3、项目目录剖析

在这里插入图片描述

2.4、ESlint代码规范及手动修复

在创建项目时,我们使用的是 JavaScript Standard Style 代码风格的规则。

  • JavaScript Standard Style (standardjs.com)
  • 看一遍,然后在写的时候, 遇到错误就查询解决

下面是这份规则中的一小部分:

  • 字符串使用单引号 – 需要转义的地方除外
  • 无分号 – 这没什么不好。不骗你!
  • 关键字后加空格 if (condition) { ... }
  • 函数名后加空格 function name (arg) { ... }
  • 坚持使用全等 === 摒弃 == 一但在需要检查 null || undefined 时可以使用 obj == null

在这里插入图片描述

如果你不认识命令行中的语法报错是什么意思,你可以根据错误代码func-call-spacing 、 space-in-parens 去 ESLint 规则列表中查找其具体含义。

  • 打开 ESLint 规则表,使用页面搜索(Ctrl + F)这个代码,查找对该规则的一个释义。

在这里插入图片描述

2.5、通过eslint插件来实现自动修正

  1. eslint会自动高亮错误显示
  2. 通过配置,eslint会自动帮助我们修复错误

在这里插入图片描述

  • 如何配置:如下图添加如下代码

在这里插入图片描述

// 当保存的时候,eslint自动帮我们修复错误
"editor.codeActionsOnSave": {
    "source.fixAll": true
},
// 保存代码,不自动格式化
"editor.formatOnSave": false
  • 注意:eslint的配置文件必须在根目录下,这个插件才能才能生效。打开项目必须以根目录打开,一次打开一个项目
  • 注意:使用了eslint校验之后,把vscode带的那些格式化工具全禁用了

settings.json 参考:

{
    "window.zoomLevel": 2,
    "workbench.iconTheme": "vscode-icons",
    "editor.tabSize": 2,
    "emmet.triggerExpansionOnTab": true,
    // 当保存的时候,eslint自动帮我们修复错误
    "editor.codeActionsOnSave": {
        "source.fixAll": true
    },
    // 保存代码,不自动格式化
    "editor.formatOnSave": false
}

3、VueRouter4

  • 官网:Vue Router (vuejs.org)
Vue版本VueRouter对应版本VueX对应版本
Vue2VueRouter3.xVueX3.x
Vue3VueRouter4.xVueX4.x
  • 路由的作用:修改地址栏路径时,切换显示匹配的组件

  • VueRouter 是 Vue 官方的一个路由插件,是一个第三方包

3.1、单页应用程序介绍

单页应用程序:SPA【Single Page Application】是指所有的功能都在一个html页面上实现

  • 单页应用网站: 网易云音乐 https://music.163.com/
  • 多页应用网站:京东 https://jd.com/

单页面应用程序,之所以开发效率高,性能好,用户体验好,最大的原因就是:页面按需更新

3.2、前端路由和后端路由

后端路由:

  • 特点:向服务器发送请求,会刷新页面,前后端不能分离
  • 在浏览器的地址栏中切换不同的url时,每次都向后台服务器发出请求,服务器根据不同的响应不同的数据,浏览器接收到数据后再进行渲染,所以后端路由会刷新页面,如果网速慢的话,就会看到一个空白页面等待服务端返回数据,后台路由最大的问题就是不能 前后端分离

前端路由:

  • 特点:不向后台发送请求,不刷新页面,前后端分离
  • 切换路由,并不刷新页面,而是根据路由在虚拟DOM中加载所需要的数据,实现页面内容的改变。

3.3、前端路由模式

前端路由有两种模式:hash 模式和 history 模式

3.3.1、hash模式

  • hash 模式是一种把前端路由的路径用井号 # 拼接在真实 URL 后面的模式。

  • 当井号 # 后面的路径发生变化时,浏览器并不会重新发起请求,而是会触发 hashchange 事件。

  • 我们可以通过直接赋值 location.href 来改变 href , 但是页面不发生刷新

在这里插入图片描述

3.3.2、history 模式

history API 是 H5 提供的新特性,允许开发者直接更改前端路由,即更新浏览器 URL 地址而不重新发起请求。

在这里插入图片描述

4、VueRouter的使用

目前前端流行的三大框架, 都有自己的路由实现:

  • Angular的ngRouter
  • React的ReactRouter
  • Vue的vue-router

我们的重点是vue-router,vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用。

vue-router是基于路由和组件的

  • 路由用于设定访问路径, 将路径和组件映射起来
  • 在vue-router的单页面应用中, 页面的路径的改变就是组件的切换

使用步骤:

  1. 使用npm create vite@latest 创建 Vue 骨架
  2. 下载VueRouter 包:
npm install vue-router@4
  1. src/router/index.js 下初始化如下代码:
    • 如果我们在使用 vueCLI 初始化项目的时候安装了 router,那么就会自动生成 router 文件夹,里面有 index.js
//所有路由的配置都放在这里

//1.引入组件
import  {createRouter,createWebHistory} from 'vue-router'
import Home from "../components/Home.vue";
import Mine from "../components/Mine.vue";


//2.创建路由对象routes
const routes = [
  //  路由重定向:当路由匹配到 `/` 时候,会重定向到 `/home` 上
  {path: '/', redirect: '/home'},
  {path: '/home',name: 'home',component:Home},
  {path: '/mine',name: 'mine',component:Mine}
]

//配置路由和组件之间的应用关系
const router = createRouter({
  history: createWebHistory(),
  routes: routes,
});

// 导出路由对象,将 router 对象传入到Vue实例
export default router
  1. main.js 中导入并挂载路由模块
import { createApp } from 'vue'
import App from './App.vue'

//1.导入路由模块
import router from "./router/index";

const app = createApp(App);

// 把 VueRouter 安装为 Vue 的插件
app.use(router);

// 挂载路由模块
app.mount('#app')
  1. App.vue 中使用路由
    • <router-link> 声明路由链接
    • <router-view> 定义路由占位符
<template>
  <div>
    <!-- 1.定义路由链接 -->
    <div id="nav">
      <router-link to="/home">首页</router-link>
      <router-link to="/mine">我的</router-link>
    </div>
    <!-- 2.定义路由的占位符 -->
    <router-view></router-view>
  </div>
</template>


<script>
  export default  {
    setup(){

    }
  }
</script>


<style scoped>

</style>

在这里插入图片描述

4.1、声明路由匹配规则

src/router/index.js 路由模块中,通过 routes 数组声明路由的匹配规则。示例代码如下:

// 在 routes 数组中,声明路由的匹配规则
const routes = [
  //  路由重定向:当路由匹配到 `/` 时候,会重定向到 `/home` 上
  {path: '/', redirect: '/home'},
  // path 表示要匹配的 hash 地址,component 表示要展示的路由组件 
  {path: '/home',name: 'home',component:Home},
  {path: '/mine',name: 'mine',component:Mine}
]

4.2、不同的历史记录模式

  • hash 模式是用 createWebHashHistory() 创建的
//配置路由和组件之间的应用关系
const router = createRouter({
  history: createWebHashHistory(),
  routes: routes,
});

它在内部传递的实际 URL 之前使用了一个哈希字符(#)。由于这部分 URL 从未被发送到服务器,所以它不需要在服务器层面上进行任何特殊处理。不过,它在 SEO 中确实有不好的影响

  • history 模式是用 createWebHistory() 创建的,推荐使用这个模式
//配置路由和组件之间的应用关系
const router = createRouter({
  history: createWebHistory(),
  routes: routes,
});

4.3、<router-link>补充

  • 在前面的 <router-link> 中,我们只是使用了一个属性:to ,用于指定跳转的路径

  • <router-link> 还有一些其他属性

    • tag可以指定 <router-link> 之后渲染成什么组件,比如下面的代码会被渲染成一个 <li> 元素,而不是 <a>

      <router-link to='/home'  tag='li'></router-link> 
      
    • replace : replace 不会留下 history 记录,所以指定 replace 的情况下,后退键返回不能返回到上一个页面中

      <router-link to="/home" replace >Home</router-link> 
      
    • active-class :当 <router-link> 对应的路由匹配成功时,会自动给当前元素设置一个 router-link-active 的 class,设置 active-class 可以修改默认的名称(一般不需要改)

      • 在进行高亮显示的导航菜单或者底部tabbar时, 会使用到该类
      • 但是通常不会修改类的属性, 会直接使用默认的router-link-active即可
  • <router-link>的作用:能跳转、能高亮

4.3.1、样式高亮

使用router-link跳转后,我们发现。当前点击的链接默认加了两个class的值 router-link-exact-activerouter-link-active

  • router-link-active模糊匹配,用的多
// 可以匹配 /my 、 /my/a 、/my/b ....
// 只要是 `/my` 开头的路径,都可以匹配到,这样都会加样式高亮
<router-link to="/my">Home</router-link> 
  • router-link-exact-active精准匹配
// 仅可匹配 /my , 匹配到会加样式高亮
<router-link to="/my">Home</router-link> 

4.3.2、自定义类名

router-link的两个高亮类名太长了,我们希望能定制怎么办

  • 在创建路由对象时,额外配置两个配置项
    • linkActiveClass
    • linkExactActiveClass
const router = createRouter({
  history: createWebHashHistory(),
  routes: routes,
  // 自定义类名
  linkActiveClass: "类名1", // 配置模糊匹配的类名
  linkExactActiveClass: "类名2" // 配置精确匹配的类名
});

在这里插入图片描述

4.4、组件的存放目录

.vue文件分为2类:

  • 页面组件 (配置路由规则时使用的组件)
  • 复用组件 (多个组件中都使用到的组件)

存放目录分开的目的就是为了更好的维护

  • src/views文件夹
    • 页面组件 - 页面展示 - 配合路由用
  • src/components文件夹
    • 复用组件 - 展示数据 - 常用于复用

Tips:

  • 脚手架环境下 @指代src目录,可以用于快速引入组件

4.5、Vue-router的常见用法

4.5.1、路由重定向

路由重定向指的是:用户在访问 地址 A 的时候, 强制用户跳转到 地址 C ,从而展示特定的组件页面。

  • 通过路由规则的 redirect 属性,指定一个新的路由地址,可以很方便地设置路由的重定向:
const routes = [
  //  路由重定向:当路由匹配到 `/` 时候,会重定向到 `/home` 上
  {path: '/', redirect: '/home'},
  {path: '/home',name: 'home',component:Home},
  {path: '/mine',name: 'mine',component:Mine}
]

4.5.2、404

404的路由,虽然配置在任何一个位置都可以,但一般都配置在其他路由规则的最后面

  • 语法:path: "*" 任意路径 - 前面不匹配就匹配最后这个
//2.创建路由对象
const routes = [
  //  路由重定向:当路由匹配到 `/` 时候,会重定向到 `/home` 上
  {path: '/', redirect: '/home'},
  {path: '/home',name: 'home',component:Home},
  {path: '/mine',name: 'mine',component:Mine},
  // 404   
  {path: '*', component: NotFind}
]

4.5.3、路由的懒加载

  • 首先, 我们知道路由中通常会定义很多不同的页面。这个页面最后被打包在哪里呢? 一般情况下, 是放在一个js文件中。但是, 页面这么多放在一个js文件中, 必然会造成这个页面非常的大。如果我们一次性从服务器请求下来这个页面, 可能需要花费一定的时间, 甚至用户的电脑上还出现了短暂空白的情况。

  • 如何避免这种情况呢? 使用路由懒加载就可以了

  • 路由懒加载的主要作用:

    • 将路由对应的组件打包成一个个的js代码块
    • 只有在这个路由被访问到的时候, 才加载对应的组件
// 原始路由加载
// import Home from '../components/Home'
// 路由懒加载(推荐)
const Home = () => imports('../components/Home')
const routes = [
  //  路由重定向:当路由匹配到 `/` 时候,会重定向到 `/home` 上
  {path: '/', redirect: '/home'},
  {path: '/home',name: 'home',component: () => import('../views/Home.vue')},
]

4.5.4、动态路由

动态路由指的是:把 Hash 地址中可变的部分定义为参数项 ,从而提高路由规则的复用性

在某些情况下,一个页面的path路径可能是不确定的,比如我们进入用户界面时,希望是如下的路径:

  • /user/aaaa/user/id

  • 除了有前面的 /user 之外,后面还跟上了用户的 ID

  • 这种 pathComponent 的匹配关系,我们称之为动态路由(也是路由传递数据的一种方式)


使用语法:在 src/router/index.js 中配置动态路由

const routes = [
  {
   // 使用英文冒号 `:` 来定义路由的参数项   
   path: '/user/:id',
   name: 'user',
   component: () => import('../views/User.vue')
  },
]

我们可以在主组件 App.vue 中模拟服务器传入userId,从而我们拼接到url中

<template>
  <div>
    <!-- 1.定义路由链接 -->
      <router-link :to="'/user/' + userId">用户</router-link>
    <!-- 2.定义路由的占位符 -->
    <router-view></router-view>
  </div>
</template>


<script>
import {ref} from 'vue'
  export default  {
    setup(){
      // 服务端获取newsId为001
      const userId = ref('001');

      return {
        userId
      }
    }

  }
</script>


<style scoped>

</style>

我们也可以在 User.vue 组件中,可以获取到 id 的值,从而展示对应的用户id

<template>
  <div id="user">
    <h2>用户id ------- {{this.$route.params.id}}</h2>
  </div>
</template>

<script>
import {useRoute} from 'vue-router'
export default {
  name: "User",
  setup(){
    // 这里也可以拿到  
    const route = useRoute()
    console.log(route.params.id)
  }
}
</script>

<style scoped>

</style>

5、编程式导航和声明式导航

在浏览器中,点击链接实现导航的方式,叫做声明式导航。例如:

  • 普通网页中点击 <a> 链接,vue 项目中点击 <router-link> 都属于声明式导航

在浏览器中,调用API方法实现导航的方式,叫做编程式导航。例如:

  • 普通网页中调用 location.href 跳转到新页面的方式,属于编程式导航(用JS代码来进行跳转)

5.0、命名路由

除了 path 之外,你还可以为任何路由提供 name

const routes = [
  {
    path: '/user/:username',
    name: 'user',
    component: User,
  },
]

要链接到一个命名的路由,可以向 router-link 组件的 to 属性传递一个对象:

<router-link :to="{ name: 'user', params: { username: 'erina' }}">
  User
</router-link>

这跟代码调用 router.push() 是一回事:

this.$router.push({ name: 'user', params: { username: 'erina' } })

在这两种情况下,路由将导航到路径 /user/erina

5.1、编程式导航API

vue-router 提供了许多编程式导航的 API,其中最常用的导航 API 分别是:

  • this.$router.push('hash地址') :跳转到指定 hash 地址,并增加一条历史记录(当用户点击浏览器后退按钮时,会回到之前的 URL)
  • this.$router.replace('hash地址') :跳转到指定的 hash 地址,并替换掉当前的历史记录
  • this.$router.go(数值n) :实现导航历史前进、后退

编程式导航有两种路由跳转方式:

  • path 路径跳转 (简易方便)

  • name 命名路由跳转 (适合 path 路径长的场景)

5.1.1、$router.push

声明式导航编程式导航
<router-link :to="...">router.push(...)
1、path跳转方式

语法:

//简单写法
this.$router.push('路由路径')

//完整写法
this.$router.push({
  path: '路由路径'
})

通过 this.$router.push() 方法,可以跳转到指定的 hash 地址,从而展示对应的组件页面。示例代码如下:

Vue2选项式API:

<template>
  <div>
      <h3>Home组件</h3>
      <button @click="gotoMovie">跳转到Movie页面</button>
  </div>
</template>

<script>
export default {
  name: "Home",
  methods: {
      gotoMovie() {
          this.$router.push('/movie')
      }
  }
}
</script>

<style scoped>

</style>

Vue3组合式API:

<template>
  <div>
      <h3>Home组件</h3>
      <button @click="gotoMovie">跳转到Movie页面</button>
  </div>
</template>

<script>
import {useRouter} from 'vue-router'
export default {
    setup(){
        // 跳转到Movie页面
        const movie = () => {
            route.push('/movie')
        }
        return {
            movie,
        }
    }
}
</script>

<style scoped>

</style>
2、path路径跳转传参(query传参)
//简单写法
this.$router.push('/路径?参数名1=参数值1&参数2=参数值2')

//完整写法
this.$router.push({
  path: '/路径',
  query: {
    参数名1: '参数值1',
    参数名2: '参数值2'
  }
})
//示例
this.$router.push({
    path:'/home',
    query:{
        id:id,
        name:jack
    }
})


//路由配置
{
    path:'/home',
    name:Home,
    component:Home
}


//组件中获取参数
this.$route.query.id

**注意:**path不能配合params使用

// `params` 不能与 `path` 一起使用
this.router.push({ path: '/user', params: { username } }) // -> /user
4、name命名路由跳转

特点:适合 path 路径长的场景

语法:

  • 路由规则,必须配置name配置项
const routes = [
  {
   path: '/path/xxx',
   name: '路由名',
   component: XXX
  },
]
  • 通过 name 来进行跳转
this.$router.push({
  name: '路由名'
})
5、name命名路由跳转传参 (query传参)
this.$router.push({
  name: '路由名字',
  query: {
    参数名1: '参数值1',
    参数名2: '参数值2'
  }
})
6、name命名路由跳转传参 (动态路由传参)
this.$router.push({
  name: '路由名字',
  params: {
    参数名: '参数值',
  }
})

name 可以 搭配 params 使用

5.1.2、$router.replace

调用 this.$router.replace() 方法,可以跳转到指定的 hash 地址,从而展示对应的组件页面。

push 和 replace 的区别:

  • push 会增加一条历史记录
  • replace 不会增加历史记录,而是替换掉当前的历史记录
声明式导航编程式导航
<router-link :to="..." replace>router.replace(...)

5.1.3、$router.go(n)

router.go(-1)  // 返回、后退一步

调用 this.$router.go() 方法,可以在浏览历史中前进和后退。

注意,一般只会前进和后退一层页面,因此 vue-router 提供了如下两个便捷方法:

  • $router.back()
    
    • 在历史记录中, 后退到上一个页面
  • $router.forward()
    
    • 在历史记录中, 前进到下一个页面
  • history.back() 等价于 history.go(-1)

  • history.forward() 等价于 history.go(1)

5.2、声明式导航

5.2.1、跳转传参

我们可以通过两种方式,在跳转的时候把所需要的参数传到其他页面中

  • 查询参数传参
  • 动态路由传参
1、查询参数传参
  • 如何传参?

    <router-link to="/path?参数名=值"></router-link>
    
  • 如何接受参数

    //固定用法
    $router.query.参数名
    

示例:

  1. 例如我们在 App.vue 里面向其他路由 /profile 传递对象参数
<router-link :to="{path:'/profile', query: {name: 'why', age: 18}}"></router-link>
  1. Profile.vue 组件里面也可以取到传递过来的参数
<template>
  <div>
      <h2>我是 Profile 组件</h2>
      <h2>{{this.$route.query}}</h2>
       <h2>{{this.$route.query.name}}</h2>
       <h2>{{this.$route.query.age}}</h2>
  </div>
</template>

<script>
export default {
  name: "Profile"
}
</script>

<style scoped>

</style>
2、动态路由传参
  • 使用英文的冒号 : 来定义路由的参数项
// 在 routes 数组中,声明路由的匹配规则
const routes = [
  // 使用英文的冒号 `:` 来定义路由的参数项
  {path: '/user/:id',name: 'user',component: User},
]

/user/:id 表示,必须要传参数。如果不传参数,也希望匹配,可以加个可选符?

// 在 routes 数组中,声明路由的匹配规则
const routes = [
  // 使用英文的冒号 `:` 来定义路由的参数项
  {path: '/user/:id?',name: 'user',component: User},
]

在 User.vue 组件中,可以获取到 id 的值,从而展示对应的用户详情

<template>
  <div class='User-container'>
    <h2>User组件 ------- {{this.$route.params.id}}</h2>
  </div>
</template>

5.2.2、使用props接收路由参数

为了简化路由参数的获取形式,vue-router 允许在 路由规则中开启 props 传参

  • 定义路由规则时,声明 props: true 选项
{
    path: '/user/:id',
    component: User,
    props: true
}
  • 在 User.vue 组件中,可以获取到 id 的值,从而展示对应的用户详情
<template>
  <div class='User-container'>
    <!-- 2.直接使用 props 中接收的路由参数 -->  
    <h2>User组件 ------- {{id}}</h2>
  </div>
</template>

<script>
export default {
  name: "User",
  props: ['id']			// 1.使用 props 接收路由规则中匹配到的参数项
}
</script>

<style scoped>

</style>
  • 在主组件 App.vue 中也可以获取到路由参数
<router-link :to=" '/user' + id ">用户</router-link>

6、 router和route的区别

  • $router 为VueRouter实例,想要导航到不同URL,则使用$router.push方法
  • $route为当前 router 跳转对象里面可以获取name、path、query、params等

7、嵌套路由

7.1、一级路由

// 在 routes 数组中,声明路由的匹配规则
const routes = [
  // 一级路由
  {path: '/user',name: 'user',component: User},
]

7.2、二级路由

二级路由也叫嵌套路由,当然也可以嵌套三级、四级…,嵌套路由是一个很常见的功能,比如在home页面中, 我们希望通过 /home/news/home/message 访问一些内容

一个路径映射一个组件, 访问这两个路径也会分别渲染两个组件

语法:

  1. 在一级路由下,配置children属性即可
  2. 配置二级路由的出口:在组件内部使用<router-view>标签
const routes = [
  {
    path: '/mine',
    component:Mine,
    children: [
      // children中的配置项 跟一级路由中的配置项一模一样 
      {path:'xxxx',component:xxxx.vue},
      {path:'xxxx',component:xxxx.vue},
    ]
  },
]
  1. 在一级路由下,配置children属性
  2. 注意:一级的路由path 需要加 / 二级路由的path不需要加 /

配置二级路由的出口:

<template>
    <div class="content">
        <router-view></router-view>
    </div>
</template>

注意: 配置了嵌套路由,一定配置对应的路由出口,否则不会渲染出对应的组件

技巧:二级路由应该配置到哪个一级路由下呢?

  • 这些二级路由对应的组件渲染到哪个一级路由下,children就配置到哪个路由下边

8、导航守卫

导航守卫可以控制路由的访问权限:

  • vue-router提供的导航守卫主要用来监听路由的进入和离开的
  • vue-router提供了beforeEachafterEach的钩子函数, 它们会在路由即将改变前和改变后触发

8.1、全局前置守卫

每次发生路由的导航跳转时,都会触发全局前置守卫 。因此,在全局前置守卫中,程序员可以对每个路由进行访问权限的控制:

  • 你可以使用 router.beforeEach 注册一个全局前置守卫:
const router = createRouter({
  history: createWebHistory(),
  routes: routes,
});

// 调用路由实例对象的 beforeEach 方法,即可声明"全局前置守卫"
// 每次发生路由跳转的时候,都会触发这个方法
// 全局前置守卫
router.beforeEach((to,from,next)=> {
    // to 是将要访问的路由的信息对象
    // from 是将要离开的路由的信息对象
    // next 是一个函数,调用 next()表示放行,允许这次路由导航
    // 返回 false 以取消导航
    return false
}) 

每个守卫方法接收两个参数:

  • to : 即将要进入的目标的路由对象
  • from:当前导航即将要离开的路由对象
  • next:调用该方法后,才能进入下一个钩子(可选)

注意:如果是前置钩子beforeEach,必须要调用 next() 函数,如果是后置钩子afterEach,不需要主动调用 next() 函数

可以返回的值如下:

  • false: 取消当前的导航。
  • 一个路由地址:通过一个路由地址跳转到一个不同的地址

8.1.1、示例

  • 网页标题是通过<title>来显示的, 但是SPA只有一个固定的HTML, 切换不同的页面时, 标题并不会改变.
  • 但是我们可以通过JavaScript来修改<title>的内容 window.document.title = '新的标题'
  • 那么在Vue项目中, 在哪里修改? 什么时候修改比较合适呢?
const routes = [
  {
    path: '',
    // redirect重定向
    redirect: '/home'
  },
  {
    path: '/home',
    component: Home,
    meta: {
        title: '首页'
    }
  },
  {
    path: '/about',
    component: About,
    meta: {
        title: '关于'
    }
  },
]
const router = createRouter({
  history: createWebHistory(),
  routes: routes,
});

// 前置钩子hook(前置回调)
router.beforeEach((to,form,next) => {
    // 从 from 跳转到 to
    window.document.title = to.meta.title
    next()
})

8.1.2、路由元信息

有时,你可能希望将任意信息附加到路由上,如过渡名称、谁可以访问路由等。这些事情可以通过接收属性对象的meta属性来实现,并且它可以在路由地址和导航守卫上都被访问到。

const routes = [
  {
    path: '/posts',
    component: PostsLayout,
    children: [
      {
        path: 'new',
        component: PostsNew,
        // 只有经过身份验证的用户才能创建帖子
        meta: { requiresAuth: true }
      },
      {
        path: ':id',
        component: PostsDetail
        // 任何人都可以阅读文章
        meta: { requiresAuth: false }
      }
    ]
  }
]

那么如何访问这个 meta 字段呢?

  • 首先,我们称呼 routes 配置中的每个路由对象为 路由记录。路由记录可以是嵌套的,因此,当一个路由匹配成功后,它可能匹配多个路由记录。

  • 例如,根据上面的路由配置,/posts/new 这个 URL 将会匹配父路由记录 (path: '/posts') 以及子路由记录 (path: 'new')。

  • 一个路由匹配到的所有路由记录会暴露为 $route 对象,Vue Router 还为你提供了一个 $route.meta 方法

这意味着你可以简单地写:

router.beforeEach((to, from) => {
  if (to.meta.requiresAuth && !auth.isLoggedIn()) {
    // 此路由需要授权,请检查是否已登录
    // 如果没有,则重定向到登录页面
    return {
      path: '/login',
      // 保存我们所在的位置,以便以后再来
      query: { redirect: to.fullPath },
    }
  }
})

8.1.2、next函数的三种调用方式

  • 当前用户拥有后台主页的访问权限,直接放行: next()
  • 当前用户没有后台主页的访问权限,强制其跳转到登录页面:next('/login')
  • 当前用户没有后台主页的访问权限,不允许跳转到后台主页:next(false)

8.2、全局后置守卫

router.afterEach((to, from) => {
  window.document.title = to.meta.title
})

它们对于分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用。

8.3、keep-alive缓存组件

  • 当路由被跳转后,原来所看到的组件就被销毁了,重新返回后组件又被重新创建

解决办法:利用keep-alive把原来的组件给缓存下来

  • keep-alive 是 Vue 的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
  • 优点:在组件切换过程中把切换出去的组件保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性。
<template>
  <div>
    <keep-alive>
      <router-view></router-view>
    </keep-alive>
  </div>
</template>

8.3.1、keep-alive的三个属性

  1. include : 组件名数组,只有匹配的组件会被缓存
  2. exclude : 组件名数组,任何匹配的组件都不会被缓存
  3. max : 最多可以缓存多少组件实例
<template>
  <div>
    <keep-alive :include="['LayoutPage']">
      <router-view></router-view>
    </keep-alive>
  </div>
</template>

路由记录。路由记录可以是嵌套的,因此,当一个路由匹配成功后,它可能匹配多个路由记录。

  • 例如,根据上面的路由配置,/posts/new 这个 URL 将会匹配父路由记录 (path: '/posts') 以及子路由记录 (path: 'new')。

  • 一个路由匹配到的所有路由记录会暴露为 $route 对象,Vue Router 还为你提供了一个 $route.meta 方法

这意味着你可以简单地写:

router.beforeEach((to, from) => {
  if (to.meta.requiresAuth && !auth.isLoggedIn()) {
    // 此路由需要授权,请检查是否已登录
    // 如果没有,则重定向到登录页面
    return {
      path: '/login',
      // 保存我们所在的位置,以便以后再来
      query: { redirect: to.fullPath },
    }
  }
})

8.1.2、next函数的三种调用方式

  • 当前用户拥有后台主页的访问权限,直接放行: next()
  • 当前用户没有后台主页的访问权限,强制其跳转到登录页面:next('/login')
  • 当前用户没有后台主页的访问权限,不允许跳转到后台主页:next(false)

8.2、全局后置守卫

router.afterEach((to, from) => {
  window.document.title = to.meta.title
})

它们对于分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用。

8.3、keep-alive缓存组件

  • 当路由被跳转后,原来所看到的组件就被销毁了,重新返回后组件又被重新创建

解决办法:利用keep-alive把原来的组件给缓存下来

  • keep-alive 是 Vue 的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
  • 优点:在组件切换过程中把切换出去的组件保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性。
<template>
  <div>
    <keep-alive>
      <router-view></router-view>
    </keep-alive>
  </div>
</template>

8.3.1、keep-alive的三个属性

  1. include : 组件名数组,只有匹配的组件会被缓存
  2. exclude : 组件名数组,任何匹配的组件都不会被缓存
  3. max : 最多可以缓存多少组件实例
<template>
  <div>
    <keep-alive :include="['LayoutPage']">
      <router-view></router-view>
    </keep-alive>
  </div>
</template>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1146201.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringCloud 微服务全栈体系(七)

第九章 Docker 一、什么是 Docker 微服务虽然具备各种各样的优势&#xff0c;但服务的拆分通用给部署带来了很大的麻烦。 分布式系统中&#xff0c;依赖的组件非常多&#xff0c;不同组件之间部署时往往会产生一些冲突。在数百上千台服务中重复部署&#xff0c;环境不一定一致…

基于SpringBoot的个人博客系统

基于SpringBootVue的个人博客系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 系统公告 博客详情 后台发文 摘要 基于Spring Boot的个人博客系统是一种…

实用搜索小技巧——站在巨人的肩膀上看世界

文章目录 1. 关于搜索效率2. 谷歌搜索语法2.1 “” 限定关键词2.2 intitle 限定标题2.3 限定关键词限定标题2.4 allintitle 标题多个关键词2.5 intext 限定内容关键词2.6 inurl 限定网址关键词2.7 site 限定网址来源2.8 imagesize 限定图片尺寸2.9 filetype 限定文件格式 3. in…

8.自定义组件布局和详解Context上下文

pages/index.vue layout布局运行在服务端 1、在项目的目录下新建layout文件夹&#xff0c;并新建一个blog.vue布局文件 2、在页面中的layout函数里&#xff0c;返回刚才新建布局文件的名字blog就可以使用了 export default {...layout (context) {console.log(context)retu…

探索Vue 3和Vue 2的区别

目录 响应式系统 性能优化 Composition API TypeScript支持 总结 Vue.js是一款流行的JavaScript框架&#xff0c;用于构建用户界面。Vue 3是Vue.js的最新版本&#xff0c;相较于Vue 2引入了许多重大变化和改进。在本文中&#xff0c;我们将探索Vue 3和Vue 2之间的区别。 …

【中国知名企业高管团队】系列50:荣耀手机

今天为您介绍中国手机的一个“新势力”——荣耀。说是“新”是因为他单独运作的时间最短&#xff0c;说他“势力”是因为他的崛起自带光环&#xff0c;市场拓展和发展让OPPO、VIVO和小米都感到巨大的压力&#xff0c;可以说中国市场的大部分份额都被苹果、华为、OPPO、VIVO、小…

图解java.util.concurrent并发包源码系列——深入理解ConcurrentHashMap并发容器,看完薪水涨一千

图解java.util.concurrent并发包源码系列——深入理解ConcurrentHashMap并发容器 HashMap简单介绍HashMap在并发场景下的问题HashMap在并发场景下的替代方案ConcurrentHashMap如何在线程安全的前提下提升并发度1.71.8 JDK1.7的ConcurrentHashMap源码JDK1.8的ConcurrentHashMap源…

2016年上半年上午易错题(软件设计师考试)

以下媒体文件格式中&#xff0c;&#xff08; 12 &#xff09;是视频文件格式。 A &#xff0e; WAV B &#xff0e; BMP C &#xff0e; MP3 D&#xff0e;MOV 以下软件产品中&#xff0c;属于图像编辑处理工具的软件是&#xff08; 13 &#xff09;。 A &#xff0e; Po…

Flask 路由机制分析之一

一、前言 《Flask Run运行机制剖析》这篇我们讲了应用启动的内部机制&#xff0c;启动后就开始监听Http请求了&#xff0c;请求过来如何跳到对应的函数执行&#xff0c;这就是路由机制。我们沿用上一篇例子&#xff0c;来探究一下app.route("/")内部干了些什么事。 …

2017年上半年上午易错题(软件设计师考试)

CPU 执行算术运算或者逻辑运算时&#xff0c;常将源操作数和结果暂存在&#xff08; &#xff09;中。 A &#xff0e; 程序计数器 (PC) B. 累加器 (AC) C. 指令寄存器 (IR) D. 地址寄存器 (AR) 某系统由下图所示的冗余部件构成。若每个部件的千小时可靠度都为 R &…

HiQPdf Library for .NET - HTML to PDF Crack

HiQPdf Library for .NET - HTML 到 PDF 转换器 .NET Core&#xff0c;用于 .NET 的 HiQPdf HTML 到 PDF 转换器 &#xff1a;HiQPdf HTML to PDF Library for .NET C# 和 HTML to PDF .NET Core 为您提供了一个现代、快速、灵活且强大的工具&#xff0c;只需几行代码即可创建复…

Python 算法高级篇:堆排序的优化与应用

Python 算法高级篇&#xff1a;堆排序的优化与应用 引言 1. 什么是堆&#xff1f;2. 堆的性质3. 堆排序的基本原理4. 堆排序的 Python 实现5. 堆排序的性能和优化6. 堆排序的实际应用7. 总结 引言 堆排序是一种高效的排序算法&#xff0c;它基于数据结构中的堆这一概念。堆排序…

给VSCode插上一双AI的翅膀

文章目录 前言一、安装DevChat1.1、访问地址1.2、注册1.3、在VSCode里安装DevChat插件1.3.1、未安装状态1.3.2、已安装状态 二、设置Access Key2.1. 点击左下角管理&#xff08;“齿轮”图标&#xff09;—命令面板&#xff08;Command Palette&#xff09;&#xff0c;如下图2…

独家揭秘|小米14魔改存储芯片多出8GB空间背后的秘诀

在昨天发表的文章下面&#xff0c;有粉丝朋友要求“评价下小米256GB多8GB的技术”。小编也是好奇&#xff0c;本文就让我们一起来看看这个“高科技”背后的秘密。&#xff08;提前声明&#xff1a;本文内容仅代表个人观点&#xff0c;如果不当之处&#xff0c;小米公司不要投诉…

09.K8S高可用-堆叠etcd拓扑测试说明

堆叠 etcd 拓扑 1、部署架构如图 2、原理说明 核心组件高可用模式高可用实现方式apiserver主备keepalived + haproxycontroller-manager主备leader electionscheduler主备leader electionetcd集群kubeadm**「vip」**由外部负载均衡器提供一个vip,流量负载到keepalived master…

vue 内置指令-v-pre/v-memo

一、v-pre 使用了该指令的元素和子元素会被编译忽略&#xff0c;也就是不进行编译&#xff0c;其中包含的所有vue模版语法都会原样显示&#xff0c;作用加快vue的编译 例子&#xff1a; <p v-pre>{{不会被编译}}<span v-text"msg"></span></p&…

2016年下半年上午易错题(软件设计师考试)

在程序运行过程中&#xff0c; CPU 需要将指令从内存中取出并加以分析和执行。 CPU 依据&#xff08; &#xff09;来区 分在内存中以二进制编码形式存放的指令和数据。 A&#xff0e;指令周期的不同阶段 B &#xff0e;指令和数据的寻址方式 C &#xff0e;指令操作码的…

基于计算机视觉的坑洼道路检测和识别-MathorCup A(深度学习版本)

1 2023 年 MathorCup 高校数学建模挑战赛——大数据竞赛 赛道 A&#xff1a;基于计算机视觉的坑洼道路检测和识别 使用深度学习模型&#xff0c;pytorch版本进行图像训练和预测&#xff0c;使用ResNet50模型 2 文件夹预处理 因为给定的是所有图片都在一个文件夹里面&#xf…

Wpf 使用 Prism 实战开发Day03

一.实现左侧菜单绑定 效果图: 1.首先需要在项目中创建 mvvm 的架构模式 创建 Models &#xff0c;放置实体类。 实体类需要继承自Prism 框架的 BindableBase&#xff0c;目的是让实体类支持数据的动态变更! 例如: 系统导航菜单实体类 / <summary>/// 系统导航菜单实体类…

AWTK 液体流动效果控件发布

液体流动效果控件。 主要特色&#xff1a; 支持水平和垂直方向。支持正向和反向流动。支持设置头尾的图片。支持设置流动的图片。支持设置速度的快慢。支持启停操作。 准备 获取 awtk 并编译 git clone https://github.com/zlgopen/awtk.git cd awtk; scons; cd -运行 生成…