Vue2:官方路由 Vue-Router 3.x

news2025/7/8 7:02:52

前端路由

前端路由:根据不同的url地址,页面上展示不同的内容(根据url地址的不同分发到不同的组件。)


SPA 介绍

spa 是 single page application 简写,意思是单页面应用程序。Vue 适合开发 spa 类型的项目。

优点:

  • 业务场景的切换,性能很好。
  • 集中维护一个网站的功能。
  • 完全的前后端分离(前后端可以并行开发,提供系统开发效率)

缺点:

  • 所有的功能集中的一个页面,依赖的资源是非常多的,加载第一次的时候很慢(首屏加载)
  • 业务复杂度很高(解决方案:vue组件、前端路由)

前端路由原理

基于 hash 的路由原理(通过地址栏 hash 字符串的改变,去更新页面的内容)

  • http://localhost:3000?username=lisi#abc
  • http://localhost:3000?username=lisi#hello
  • 锚点 (hash) 作用:跳转到网页的某一个位置
  • 锚点的变化不会导致浏览器重新向服务器发送一个请求。

Vue 路由

vue-router 是基于 vue 的 js 插件,实现了前端路由功能。

下载地址:https://unpkg.com/vue-router/dist/vue-router.js

Vue Router 3.x 是针对 Vue2 版本的官方路由。


组件分类

vue 文件分为两类,一个是页面组件,一个是复用组件。

  • 页面组件:页面展示 - 配合路由用
  • 复用组件:展示数据 / 常用于复用

src/views(或pages) 文件夹下的页面组件,配合路由切换。

src/components 文件夹下的一般引入到 src/views 下的 vue 中复用展示数据。

基本使用

基于 url 地址的变化实现组件的切换。一切都围绕着hash值变化为准。

使用流程:下载路由,编写对应规则注入到vue实例上,使用router-view 挂载点显示切换的路由。

main.js

导入组件时,可以使用 @ 代替 ./,@的意思是在src文件夹下找文件。

// 引入Router
import VueRouter from 'vue-router'
// 使用路由插件
Vue.use(VueRouter)

// 导入要切换的组件
import Find from './views/Find.vue'
import My from '@views/My.vue'
import Part from '@views/part.vue'

// 创建路由规则数组
const routes = [
  {
    path: "/find",
    component: Find
  },
  {
    path: "/my",
    component: My
  },
  {
    path: "/part",
    component: Part
  }
]

// 创建路由对象,传入规则
const router = new VueRouter({
  routes
})

// 关联到Vue实例
new Vue({
  router,
})

App.vue

components 换成 router-view,用于组件内容渲染的地方。

<template>
  <div>
    <div class="footer_wrap">
      <a href="#/find">发现音乐</a>
      <a href="#/my">我的音乐</a>
      <a href="#/part">朋友</a>
    </div>
    <div class="top">
      <router-view></router-view>
    </div>
  </div>
</template>

声明式导航

vue-router 提供了一个全局组件 router-link

  • router-link 实质上最终会渲染成 a 链接,to 属性等价于提供 href 属性,但是 to 属性不需要加 # ,直接写/组件名 就可以。

  • router-link 提供了声明式导航高亮的功能(自带类名)

App.vue

<template>
  <div>
    <div class="footer_wrap">
      <router-link to="/find">发现音乐</router-link>
      <router-link to="/my">我的音乐</router-link>
      <router-link to="/part">朋友</router-link>
    </div>
    <div class="top">
      <router-view></router-view>
    </div>
  </div>
</template>

跳转传参

在跳转路由时,给路由组件对应的组件内传值。

router-link 的 to 属性传值:

  • /path?参数名=值
    

    /pash/ 值:需要路由对象提前配置 path: “/pash/参数名”

对应页面组件接收传递过来的值:

  • $route-query.参数名
    
  • $route.params.参数名
    
语法格式

: 的路径代表要接收具体的值

App.vue

<router-link to="/part?name=小传">朋友-小传</router-link>
<router-link to="/part/小智">朋友-小智</router-link>

main.js

通过 params 传参,要使用路由定义。

// 创建路由规则数组
const routes = [
  {
    path: "/part",
    component: Part
  },
  {
    path: "/part/:username",
    component: Part
  }
]

part.vue

<template>
  <div>
      <p>人名: {{ $route.query.name }} -- {{ $route.params.username }}</p>
  </div>
</template>

重定向和模式

重定向

匹配 path 后,强制切换到目标 path上。

  • 网页打开 url 默认 hash 值是 /路径。
  • redirect 是设置要重定向到哪个路由路径。

应用场景:当网站需要一个默认页面时,可以将默认页强制重定向到首页。

  • 注意:强制重定向后,还会重新匹配一次数组中的规则。
const routes = [
	{
		path: "/",
		redirect: "/find"
	},
]

404页面

如果路径 hash 值,没有和数组里的规则匹配,则默认给一个 404 页面。

语法:路由最后,path 匹配 * (任意路径) - 前面不匹配就命中最后这个,显示对应组件页面。

const routes = [
  {
    path: "*",
    component: NotFound
  }
]
<router-link to="/404">404</router-link>

模式设置

hash 路由:http://localhost:8080/#/home

history路由:http://localhost:8080/home(以后上线需要服务器端支持,否则找的是文件夹)

区别:

  • hash (url中#后面的部分)虽然出现在 URL 中,但不会被包含在 http 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。

  • history 利用了 html5 history interface 中新增的 pushState() 和 replaceState() 方法。这两个方法应用于浏览器记录栈

    hash 路由 和 history 路由一个加 #,一个不加 #

main.js

const router = new VueRouter({
  routes,
  mode: "history" // 打包上线后需要后台支持, 模式是 hash
})

编程式导航

用 Js 代码跳转。

<template>
  <div>
    <span @click="goFn('/find')">发现音乐</span>
    <span @click="goFn('my')">我的音乐</span>
    <span @click="goFn('part')">朋友</span>
  </div>
</template>

<script>
export default {
  methods: {
    goFn(targetPath) {
      this.$router.push({
        path: targetPath,
      })
    }
  }
}
</script>

多次点同一个按钮,会报错误:避免重复导航到当前位置:“/my”。

7b09fd8ba95d4537863cd80524cf23d4

解决这个错误,要在 router/index.js 中重写push方法,忽略报错

// 原来的 push
let originPush = VueRouter.prototype.push;
// 重写push方法
VueRouter.prototype.push = function (location) {
  return originPush.call(this, location).catch(err => err);
}

跳转传参

name 属性只有在js才会有用,决定跳转到哪里,其他时候选写。

语法格式

query需要 path 传值,使用path时,会忽略 params参数。

params 需要 name 传值,name支持query 和 params传参。

this.$router.push({
	path: "路由路径",
    query: {
        "参数名":},
    
    name: "路由名",
    params: {
        "参数名":}
})

// 对应路由接收参数:$route.params.参数名
// 对应路由接收参数:$route.query.参数名

使用path时,会自动忽略params

My.vue

<template>
  <div>
    <h1>My Music</h1>
    <span @click="goFn('find')">发现音乐-编程式导航</span>
    <br />
    <span @click="goQuery">我的音乐-编程式导航query</span>
    <br />
    <span @click="goParams">朋友-编程式导航params</span>
  </div>
</template>

<script>
export default {
  methods: {
    goFn(targetPath) {
      this.$router.push({
        path: targetPath,
      })
    },
    goQuery () {
      this.$router.push({
        path: 'part',
        query: {
          name: '小传'
        }
      })
    },
    goParams () {
      this.$router.push({
        path: '/part',
        params: {
          username: '小智'
        }
      })
    }
  }
}
</script>

part.vue

<template>
  <div>
      <h4>{{ $route.query.name }} -- {{ $route.params.username }}</h4>
  </div>
</template>

嵌套和守卫

路由嵌套

在一级路由下,嵌套二级路由。

思路:

  1. 在子组件中新建 router-link 标签,链接二级路由。

  2. 在 router/index.js 中的路由规则数组中,给一级路由添加 name 属性和 children 属性。

    children 属性中和一级路由一样,有路径 (path) 和 组件 (component)。

语法格式:

const routes = [
    // 一级路由1
    {
        path: '/find',
        component: Find,
        name: "Find",
        children: [
            // 二级路由1
            {
                path: '/find/',
                component: Recommend
            },
        ]
    }
]

Find.vue

<template>
	<div>
		<div class="nav_main">
			<router-link to="/find/recommend">推荐</router-link>
			<router-link to="/find/ranking">排行榜</router-link>
			<router-link to="/find/songlist">歌单</router-link>
		</div>

		<div style="1px solid red;">
			<router-view></router-view>
		</div>
	</div>
</template>

<style scoped>
.nav_main {
	background-color: red;
	color: white;
	padding: 10px 0;
}
.nav_main a {
	text-align: center;
	text-decoration: none;
	color: white;
	font-size: 12px;
	margin: 7px 17px 0;
	padding: 0px 15px 2px 15px;
	height: 20px;
	display: inline-block;
	line-height: 20px;
	border-radius: 20px;
}
.nav_main a:hover {
	background-color: brown;
}
.nav_main .router-link-active {
	background-color: brown;
}
</style>

router/index.js

路由规则数组在一级路由下写 children 属性,代表当前的二级路由。

const routes = [
  {
    path: "/find",
    component: Find,
    // 二级路由
    name: "Find",
    children: [
      {
        path: "recommend",
        component: Recommend
      },
      {
        path: "ranking",
        component: Ranking
      },
      {
        path: "songlist",
        component: SongList
      }
    ]
  },
  // 404: 只需要在一级栏里给一个全局使用
  {
    path: "*",
    component: NotFound
  },
]

类名区分

  • router-link-exact-active(精确匹配)url 中 hash 值路径,与 href 属性值完全相同,设置此类名。
  • router-link-active(模糊匹配)url 中 hash 值,包含 href 属性值这个路径。

全局前置守卫

路由跳转之前,先执行前置守卫函数,判断是否可以正常跳转。

语法格式:

router.beforeEach((to, from, next) => {
    if (to.path == '目标页面' && 登录状态 == false) {
        // 未登录执行代码块。
        next(false);	// 阻止跳转
    } else {
        next();		// 已登录,放行
    }
})

属性:

  • to:要跳转的路由。
  • from:从哪里跳转的路由。
  • next:函数体。

应用场景:在跳转路由之前,判断用户是否登录,为登录弹窗提示,登录后跳转到 我的音乐 页面。

const router = new VueRouter({
  routes,
})

// 模拟登录状态
let isLogin = false;

router.beforeEach((to, from, next) => {
    if (to.path == '/find' && isLogin == false) {
        alert('请登录');
        next(false);	// 阻止跳转
    } else {
        next();		// 放行
    }
})

vant 组件库

vant 是一个轻量、可靠的移动端Vue组件库,开箱即用。

官网地址:https://vant-contrib.gitee.io/vant/#/zh-CN/

特点:

  • 提供60多个高质量组件,覆盖移动端各类场景。
  • 性能极佳,组件平均体积不到 1kb。
  • 完善的中英文文档实例。
  • 支持 Vue2 & Vue3。
  • 支持按需引入和主题定制。

全部引入

  1. 全部引入,快速开始:https://vant-contrib.gitee.io/vant/#/zh-CN/quickstart
  2. 下载vant 组件库到当前项目中。
  3. 在 main.js 中全局导入所有组件。
  4. 使用按钮组件,作为示范的例子。

方式一:导入所有组件

Vant 支持一次性导入所有组件,引入所有组件会增加代码包体积,不推荐。

  1. 下载 vant 组件

    yarn add vant -D
    
  2. 导入所有组件,到 main.js 中

    import Vue from 'vue';
    import Vant from 'vant';
    import 'vant/lib/index.css';
    
    Vue.use(Vant);
    
  3. 使用按钮组件

    https://vant-contrib.gitee.io/vant/#/zh-CN/button

    <van-button type="primary">主要按钮</van-button>
    <van-button type="info">信息按钮</van-button>
    <van-button type="default">默认按钮</van-button>
    <van-button type="warning">警告按钮</van-button>
    <van-button type="danger">危险按钮</van-button>
    

方式二:手动按需求引入

只引入使用的组件。

在不使用插件的情况下,可以手动引入需要的组件。

  1. 手动单独引入,快速开始:https://vant-contrib.gitee.io/vant/#/zh-CN/quickstart

    import Button from 'vant/lib/button';	// button 组件
    import 'vant/lib/button/style';	// button 样式
    
  2. 注册

    components: {
    	VanButton: Button	// 手动注册组件名
    	[Button.name]: Button	// 等价的
    }
    
  3. 使用

    <van-button type="primary">主要按钮</van-button>
    <van-button type="info">信息按钮</van-button>
    <van-button type="default">默认按钮</van-button>
    <van-button type="warning">警告按钮</van-button>
    <van-button type="danger">危险按钮</van-button>
    

方式三:自动按需求引入

按需求加载组件。

babel-plugin-import 是一款 babel 插件,他会在编译过程中将import 的写法自动转换为按需求引入的方式。

  1. 安装插件

    yarn add babel-plugin-import -D
    
  2. 在 babel 配置文件里 (babel.config.js)

    module.exports = {
      plugins: [
        ['import', {
          libraryName: 'Vant',
          libraryDirectory: 'es',
          style: true
        }, 'vant']
      ]
    }
    
  3. 全局注册 (main.js)

    import Vue from 'vue'
    
    import 'vant/lib/index.css'
    import { Button } from 'vant'
    Vue.use(Button);
    

弹出框使用

弹出模态框,常用于消息提示、消息确认,或在当前页面内完成特定的交互操作。

https://vant-contrib.gitee.io/vant/#/zh-CN/dialog

<template>
	<div>
    	<van-button type="primary" @click="btn">提示弹窗</van-button>
    </div>
</template>

<script>
    // 导入提示弹窗
    import { Dialog } from "vant";

    export default {
        methods: {
            btn() {
                // 属性
                Dialog({
                    title: '标题',
                    message: "提示",
                    showCancelButton: true
                });
            },
        }
    };
</script>

Dialog 是一个函数,调用后会直接在页面中弹出相应的模态框。

Dialog 是一个方法,要在需要使用的组件中导入,不可以在 main.js 中导入。

  • title:提示框的标题
  • message:提示内容
  • showCanceButton:是否带取消按钮。
    • true:带取消按钮,相当于 Dialog.confirm()
    • false:不带取消按钮,相当于 Dialog.alert()

表单使用

用于数据录入、校验,支持输入框、单选框、复选框、文件上传等类型,需要与 Field 输入框 组件搭配使用。2.5 版本开始支持此组件。

https://vant-contrib.gitee.io/vant/#/zh-CN/form

导包
import { Form, Field } from 'vant'
Vue.use(Form);
Vue.use(Field);
语法格式
<van-form validate-first @failed="onFailed">
    <van-field
		v-model="输入框的值"
		name="表单名字"
		placeholder="表单提示信息"
		:rules="[{ 校验规则, 属性 }]"
	/>
</van-form>
校验规则

通过 rules 定义表单校验规则。

键名说明类型
required是否为必选字段boolean
message v2.5.3错误提示文案string | (value, rule) => string
validator v2.5.3通过函数进行校验(value, rule) => boolean | Promise
pattern v2.5.3通过正则表达式进行校验RegExp
trigger v2.5.2本项规则的触发时机,可选值为 onChangeonBlurstring
formatter v2.5.3格式化函数,将表单项的值转换后进行校验(value, rule) => any

登录框

<van-form @submit="onSubmit">
    <van-field
               v-model="username"
               name="username"
               label="username"
               placeholder="用户名"
               :rules="[{ required: true, message: '请填写用户名' }]"
               />
    <van-field
               v-model="password"
               type="password"
               name="password"
               label="password"
               placeholder="密码"
               :rules="[{ required: true, message: '请填写密码' }]"
               />
    <div style="margin: 16px;">
        <van-button round block type="info" native-type="submit">
            提交
        </van-button>
    </div>
</van-form>

<script>
    export default {
        data() {
            return {
                username: '',
                password: '',
            };
        },
        methods: {
            onSubmit(values) {
                console.log('submit', values);
            },
        },
    };
</script>

跨域

端口不一样,

反向代理解决跨域

本地 node 服务器开启 cors,负责请求的转发和数据接收回传。

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

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

相关文章

Django 所带的用户auth_user的坑点,authenticate()校验一直为None,校验与创建所遇到的问题整理与解决

整理一下django中用户模块自定义model后登录的一些问题&#xff1a; 网上的报错解决不是万能方案&#xff0c;主要还是要自主分析原因&#xff0c;有的是有用但是导包之类的也要看清楚因为自己修改了所以有所变得&#xff0c;不自定义的话又不太好用。 在项目初期决定使用auth…

鸡卵白蛋白偶联脂多糖(OVA-LPS),麻黄多糖修饰卵白蛋白(PB-OVA)

产品名称&#xff1a;鸡卵白蛋白偶联脂多糖 英文名称&#xff1a;OVA-LPS 用途&#xff1a;科研 状态&#xff1a;固体/粉末/溶液 产品规格&#xff1a;1g/5g/10g 保存&#xff1a;冷藏 储藏条件&#xff1a;-20℃ 储存时间&#xff1a;1年 脂多糖&#xff08;Lipopolysacchar…

第四站:数组

目录 一、一维数组的创建和初始化 1.数组的创建 &#xff08;1&#xff09;基本定义&#xff0c;创建方式 &#xff08;2&#xff09;经典的错误标准的零分 2.数组的初始化 3.一维数组的使用 4.一维数组在内存中的存储 二、二维数组的创建和初始化 1.二维数组的创建 2…

SpringBoot SpringBoot 开发实用篇 2 配置高级 2.2 松散绑定

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 开发实用篇 文章目录SpringBootSpringBoot 开发实用篇2 配置高级2.2 松散绑定2.2.1 问题引入2.2.2 松散绑定2.2.3 小结2 配…

MySQL学习笔记:模型2

序言 《MySQL45讲》 为什么表数据删除一半&#xff0c;表文件大小不变&#xff1f; 表数据既可以存在共享表空间里&#xff0c;也可以是单独的文件。这个行为是由参数 innodb_file_per_table 控制的&#xff1a; 这个参数设置为 OFF 表示的是&#xff0c;表的数据放在系统共…

错字修改 | 布署1个中文文文本拼蟹纠错模型

内容一览&#xff1a;中文文本错误的种类之一为拼写错误&#xff0c;本篇文章为利用 BART 预训练方法实现中文文本纠错功能的模型部署教程。 关键词&#xff1a;BART 中文拼写纠错 NLP 本文首发自微信公众号&#xff1a;HyperAI超神经 中文文本错误3大障碍&#xff1a;拼写、语…

Chapter9.1:线性系统的状态空间分析与综合(上)

此系列属于胡寿松《自动控制原理题海与考研指导》(第三版)习题精选&#xff0c;仅包含部分经典习题&#xff0c;需要完整版习题答案请自行查找&#xff0c;本系列属于知识点巩固部分&#xff0c;搭配如下几个系列进行学习&#xff0c;可用于期末考试和考研复习。 自动控制原理(…

第六节.常用Linux命令—chmod修改目录权限,组管理,用户管理

第六节.常用Linux命令—chmod修改目录权限&#xff0c;组管理&#xff0c;用户管理 1. chmod&#xff1a;可以修改用户/文件/目录的权限 1).命令格式: chmod(代表增加权限)/-(代表减少权限) r(可读权限)w(可写权限)x(可执行权限) 文件名/目录名 2.组管理&#xff1a; 1).终端…

年产5000吨饼干食品加工厂的工艺设计

目 录 摘 要 I Abstract II 第1章 绪论 1 1.1概述 1 1.2饼干的特点 1 1.2.1适宜大规模生产 1 1.2.2容易消化吸收 1 1.2.3食用方便 1 1.2.4营养价值高 2 1.3设计依据 2 1.4 设计范围 2 1.4.1 一般部分 2 1.4.2 重点部分 2 1.4.3 图纸 3 1.5设计指导思想 3 1.5.1 指导思想 3 1.5.…

org.activiti.validation.validator

org.activiti.validation.validator目录概述需求&#xff1a;设计思路实现思路分析1.ActivitiEventListenerValidator3.AssociationValidator4.validateAtLeastOneExecutable5.DataObjectValidator拓展实现参考资料和推荐阅读Survive by day and develop by night. talk for im…

【信号和槽】

前言 信号和槽是QT界面框架的一个核心特性&#xff0c;其重要性和MFC的消息映射机制一样。只要用QT开发项目&#xff0c;就一定会用到&#xff0c;所以必须100%熟练掌握&#xff0c;烂熟于心。 0x0 需要理解的概念 信号&#xff1a;特定情况下被发射的事件。鼠标单击按钮&…

基于复合粒子群优化的模糊神经预测控制的研究(Matlab代码实现)

&#x1f352;&#x1f352;&#x1f352;欢迎关注&#x1f308;&#x1f308;&#x1f308; &#x1f4dd;个人主页&#xff1a;我爱Matlab &#x1f44d;点赞➕评论➕收藏 养成习惯&#xff08;一键三连&#xff09;&#x1f33b;&#x1f33b;&#x1f33b; &#x1f34c;希…

boot+mp搭建版本踩坑记录

最近项目搭建中遇到的一些问题,涉及到 mp 版本 swagger集成等 文章目录前言一、引入mp启动报错1 相关配置2 报错 如下3 解决方案二、引入swagger1 引入的pom2 报错如下:3 解决方案三. 项目启动自动打开swagger页面总结前言 由于使用高版本springboot 导致集成遇到的一些问题 一…

Spring Boot+Netty+Websocket实现后台向前端推送信息

Netty 是一个利用 Java 的高级网络的能力&#xff0c;隐藏其背后的复杂性而提供一个易于使用的API的客户端/服务器框架。 可能在此之前你没有接触过&#xff0c;不过不要担心&#xff0c;下面我们通过一个消息推送的例子来看一下netty是怎么使用的。 1.添加Maven依赖 <!--…

动态代理静态代理

一、使用背景 将目标类包裹起来&#xff0c;对目标类增加一个前置操作和一个后置操作&#xff0c;比如添加日志&#xff0c;在调用目标类前、调用目标后添加日志。 感觉静态代理与动态代理的核心思想&#xff0c;都是根据目标类&#xff0c;拿到目标实现的接口&#xff0c;和…

【软考】-- 操作系统(上)

目录&#xff1a;操作系统&#xff08;上&#xff09;第一节 操作系统概述&#x1f384;一、操作系统基本概念1️⃣操作系统的五大部分&#xff1a;&#x1f38b;二、操作系统的分类1️⃣批处理操作系统&#xff1a;2️⃣分时操作系统&#xff1a;3️⃣实时操作系统&#xff1a…

STC51单片机28——跑马灯

//使用P1口流水点亮8位LED #include<reg51.h> //包含单片机寄存器的头文件 /**************************************** 函数功能&#xff1a;延时一段时间 *****************************************/ void delay(void) { unsigned char i,j; for(i…

Jetpack Compose 重写TopAppBar 实现标题多行折叠

没有效果图一律当水贴处理 效果动图 前言 想用composes实现类似CSDN的文章详细页面的标题栏 上滑隐藏标题后标题栏显示标题 compose.material3下的TopAppBar不能嵌套滚动 MediumTopAppBar 便使用了MediumTopAppBar一开始用着没什么问题&#xff0c;但是标题字数多了&…

一天完成react面试准备

什么是 React的refs&#xff1f;为什么它们很重要 refs允许你直接访问DOM元素或组件实例。为了使用它们&#xff0c;可以向组件添加个ref属性。 如果该属性的值是一个回调函数&#xff0c;它将接受底层的DOM元素或组件的已挂载实例作为其第一个参数。可以在组件中存储它。 ex…

字体图标以及svg图片的使用vite和webpack

先说下字体图标的使用 首先去阿里巴巴矢量图标库&#xff0c;选择你需要的图标&#xff08;可将svg图片自己上传&#xff09;添加到项目里&#xff0c;可以生成在线链接&#xff0c;或者下载资源包到本地。 资源包形式&#xff1a;在项目里创建一个fonts文件夹&#xff0c;将下…