一、使用vue-router构造函数
1. 下载 vue-router 模块到当前工程
代码语言:bash复制yarn add vue-router
2. 在src/main.js中引入VueRouter函数
代码语言:javascript复制// 引入路由
import VueRouter from "vue-router";
3. 在src/main.js中使用Vue.use()方法注册全局VueRouter
代码语言:javascript复制添加VueRouter到Vue.use()身上,注册全局RouterLink和RouterView组件
// 注册全局
Vue.use(VueRouter)
4. 在src/main.js中创建路由规则数组:路由字典 – 路径和组件名对应关系
代码语言:javascript复制什么是路由字典: 专门保存地址栏中相对路径与组件对象之间对应关系的一个数组。 创建路由字典(需要准备切换的页面组件)把准备好的页面组件导入到main.js中
const routes = [
{
path: "/",
redirect: "find", //默认显示推荐组件(路由的重定向)
},
{
path: "/find",
name: "Find",
component: Find, //二级路由
children: [
{
path: "/",
redirect: "recom", //默认显示推荐组件
},
{
path: "ranking", //注意二级路由的路径千万不要加/
component: Ranking,
},
{
path: "songlist",
component: SongList,
},
],
},
{
path: "/my",
name: "My",
component: My,
},
{
path: "/part",
name: "Part",
component: Part,
},
{
path: "*", //也可以写为"/*"
component: NotFound, //定义找不到已有组件时显示404
},
];
5. 在main.js中使用VueRouter构造函数生成路由对象
代码语言:javascript复制什么是路由(器)对象: 专门负责监控地址栏变化,并根据地址栏变化查找对应组件,替换页面中router-view的 核心对象
// 使用new调用VueRouter构造函数创建路由对象并且传入规则
const router = new VueRouter({ //
routes,
mode: "history", //路由模式(默认为hash模式)
});
番外:路由模式 (1) hash —— 即地址栏 URL 中的 # 符号 hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 http://www.abc.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。 (2) history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState()方法 history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如http://www.abc.com/book/id。如果后端缺少对 /book/id 的路由处理,将返回 404 错误。
6. 在main.js中把路由对象注入到new Vue实例中
代码语言:javascript复制new Vue({
router, //导入路由对象
render: (h) => h(App),
}).$mount("#app");
7. 用router-view作为挂载点, 切换不同的路由页面
当地址栏中url的相对路径切换时,router对象会自动获得新的相对地址。自动去routes中查找对应的组件对象。最后用找到的组件对象代替<router-view>的位置。
router-view 实现路由内容的地方,引入组件时写到需要引入的地方。需要注意的是,使用vue-router控制路由则必须以router-view标签作为容器。(可以先引入根组件App.vue中进行自测)
项目入口文件:main.js
代码语言:javascript复制// 导入Vue构造函数
import Vue from 'vue'
import App from './App.vue';
// 导入路由VueRouter构造函数
import VueRouter from 'vue-router';
import Details from "../components/Details.vue";
import HellWold from "../components/HelloWorld.vue";
import Find from "../components/Find.vue";
import My from "../components/My.vue";
import Part from "../components/Part.vue";
import NotFound from "../components/NotFound.vue";
import Recom from "../components/two/Recom.vue";
import Ranking from "../components/two/Ranking.vue";
import SongList from "../components/two/SongList.vue";
// 生产提示
// 改成false是用来关闭开发者提示
Vue.config.productionTip = false
//调用构造函数Vue的use方法 传入VueRouter构造函数
//作用是把VueRouter作为一个插件 全局插入到Vue中
Vue.use(VueRouter)
// 创建路由规则:定义一个路由数组对象
var routes = [
/**
*一个对象就对应了一个路由
*path 就是路由的地址
*name 给路由起的名字
*component 具体跳转的是哪个组件页面
*/
{
// path: '/' 根页面,表示已进入就显示的页面
path: "/",
// 路由重定向:redirect意味着重定向,当浏览器访问'/'根路径时,将会自动重定向到'/find'
redirect: "find", //默认显示推荐组件(路由的重定向)
},
{
path: "/find",
name: "find",
component: Find,
children: [
{
// Vue中如何实现路由跳转时单页面只含子路由的内容?
// 子路由的组件必定在上一级路由中的 router-view 中显示,可以通过条件判断,将父组件的内容隐藏,或者导向新的页面
path: "/",
redirect: "recom", //默认显示推荐组件
},
{
path: "recom",
component: Recom,
},
{
path: "ranking", //注意二级路由的路径千万不要加斜杠/
component: Ranking,
},
{
path: "songlist",
component: SongList,
},
],
},
{
path: "/my",
name: "my",
component: My,
},
{
path: "/part",
name: "part",
component: Part,
},
{
path: "/helloworld",
name: "helloworld",
component: HellWold,
},
{
path: "/details",
name: "details",
component: Details,
},
{
// path:'*' 必须要放最后
// path:'*' 表示上面的路由没有匹配到,则进入下面的页面
path: "*", //也可以写为"/*"
name: "NotFound",
component: NotFound, //定义找不到已有组件时显示404
},
];
// 实例化构造函数 VueRouter 产生一个实例化对象
// 并把上面的路由数组对象routes当作参数,以对象的方式传给构造函数 VueRouter
const router = new VueRouter({
routes, // 引入路由规则routes
mode: "history", //路由模式(默认为hash模式)
});
// 挂载
/**
* 在Vue的对象参数里面配置 el:"#app" 等于 .$mount('#app')
* 都是用来挂载到id为#app的div上的
* 把路由实例化对象router配置在Vue中,作用是保证项目中
* 所有的vue文件都可以使用router路由的属性和方法
*/
new Vue({
router, // 注入路由对象
// render函数渲染DOM结构,创建虚拟节点VNode。会把所有vue文件渲染到App组件上件上
render: h => h(App),
}).$mount('#app') // 若没有配置el属性,就需要使用$mount()函数手动挂载,等同于el:"#app""#app"
番外:当然,我们也可以在一个单独的index.js文件里面创建路由字典以及路由器对象并将路由字典传入路由器对象中中,比如,我们在src文件夹下,新建一个router文件夹,里面存放index.js。然后把index.js文件导入main.js即可。把路由文件项目入口文件main.js分开,是推荐的比较规范的做法。附:各个页面文件代码如下: 注意!在index.js文件中,不要忘记导入与路由字典对应的各个页面组件以及vue-router ,并且最后要加一句导出路由对象的代码:export default router
vue脚手架项目结构,如下:
vue版本及安装各依赖的版本情况,如下:
页面组件之间的跳转演示,如下:
- 路由文件——
src/router/index.js
// 导入路由VueRouter构造函数
// 因为涉及路由规则以及路由器对象,所以需要引入VueRouter
import VueRouter from "vue-router";
// 以下是各个页面组件的引入
import Details from "../components/Details.vue";
import HellWold from "../components/HelloWorld.vue";
import Find from "../components/Find.vue";
import My from "../components/My.vue";
import Part from "../components/Part.vue";
import NotFound from "../components/NotFound.vue";
// 创建路由规则:定义一个路由数组对象
var routes = [
/**
*一个对象就对应了一个路由
*path 就是路由的地址
*name 给路由起的名字
*component 具体跳转的是哪个组件页面
*/
{
// path: '/' 根页面,表示已进入就显示的页面
path: "/",
// 路由重定向:redirect意味着重定向,当浏览器访问'/'根路径时,将会自动重定向到'/find'
redirect: "find", //默认显示推荐组件(路由的重定向)
},
{
path: "/find",
name: "find",
component: Find,
children: [
{
// Vue中如何实现路由跳转时单页面只含子路由的内容?
// 子路由的组件必定在上一级路由中的 router-view 中显示,可以通过条件判断,将父组件的内容隐藏,或者导向新的页面
path: "/",
redirect: "recom", //默认显示推荐组件
},
{
path: "recom",
component: Recom,
},
{
path: "ranking", //注意二级路由的路径千万不要加斜杠/
component: Ranking,
},
{
path: "songlist",
component: SongList,
},
],
},
{
path: "/my",
name: "my",
component: My,
},
{
path: "/part",
name: "part",
component: Part,
},
{
path: "/helloworld",
name: "helloworld",
component: HellWold,
},
{
path: "/details",
name: "details",
component: Details,
},
{
// path:'*' 必须要放最后
// path:'*' 表示上面的路由没有匹配到,则进入下面的页面
path: "*", //也可以写为"/*"
name: "NotFound",
component: NotFound, //定义找不到已有组件时显示404
},
];
// 创建路由器对象
// 实例化构造函数 VueRouter 产生一个实例化对象
// 并把上面的路由数组对象routes当作参数,以对象的方式传给构造函数 VueRouter
const router = new VueRouter({
routes,
mode: "history", //路由模式(默认为hash模式)
});
// 导出路由器对象
// 把实例化路由对象 router 默认导出
export default router;
- 项目入口文件——
src/main.js
// 导入vue构造函数
import Vue from 'vue'
// 导入根组件——项目主组件,页面入口文件,vue页面资源的首加载项
import App from './App.vue';
// 导入路由VueRouter构造函数
// 需要注册全局VueRouter,所以引入VueRouter
import VueRouter from 'vue-router';
// 导入路由文件
//导入router文件夹中的index.js中的router实例化对象
//一个文件夹里面只有一个index.js文件在脚手架中可以把./router/index.js简写为./router
import router from './router'
// 生产提示
// 改成false是用来关闭开发者提示
Vue.config.productionTip = false
// 注册全局VueRouter
// 调用构造函数Vue的use方法 传入VueRouter构造函数
// 作用是把VueRouter作为一个插件 全局插入到Vue中
Vue.use(VueRouter)
// 挂载div#app
/**
* 在Vue的对象参数里面配置 el:"#app" 等于 .$mount('#app')
* 都是用来挂载到id为#app的div上的
* 把路由实例化对象router配置在Vue中,作用是保证项目中
* 所有的vue文件都可以使用router路由的属性和方法
*/
new Vue({
router, // 注入路由对象
// render函数渲染DOM结构,创建虚拟节点VNode。会把所有vue文件渲染到App组件上
render: h => h(App),
}).$mount('#app') // 若没有配置el属性,就需要使用$mount()函数手动挂载,等同于el:"#app"
- 项目根组件——
src/App.vue
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png" />
<HellWold></HellWold>
<hr>
<div id="nav">
<!--使用 router-link 组件进行导航 -->
<!--通过传递 `to` 来指定链接 -->
<!--`<router-link>` 将呈现一个带有正确 `href` 属性的 `<a>` 标签-->
<router-link to="/find">发现音乐</router-link>
<router-link to="/my">我的音乐</router-link>
<router-link to="/part">我的朋友</router-link>
</div>
<hr>
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
</div>
</template>
<script>
import HellWold from "./components/HelloWorld.vue";
export default {
name: "App",
components: {
HellWold,
},
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
#nav {
display: flex;
justify-content: space-around;
}
a {
text-decoration: none;
}
</style>
- 页面组件——
Find.vue
<template>
<div class="find">我是发现页
<!-- 用于展示二级路由默认路由Recom -->
<!-- 进入根路径,自动重定向到Find组件页面,然后有重定向到二级默认路由组件Recom -->
<router-view></router-view>
</div>
</template>
<script>
export default{
name:"Find"
};
</script>
<style scoped>
.find{
color: blue;
font: italic 700 25px Arial;
}
</style>
- 页面组件Find的二级默认组件——
Recom.vue
<template>
<div class="recom">
<router-link to="/details">recom...</router-link>
</div>
</template>
<script>
export default {
name: "Recom",
};
</script>
<style scoped>
</style>
- 页面组件Find的二级组件——
Ranking.vue
<template>
<div class="ranking">
<router-link to="/details">ranking...</router-link>
</div>
</template>
<script>
export default {
name: "Ranking",
};
</script>
<style scoped></style>
- 页面组件Find的二级组件——
SongList.vue
<template>
<div class="songList">
<router-link to="/details">songlist...</router-link>
</div>
</template>
<script>
export default {
name: "SongList",
};
</script>
<style scoped>
</style>
- 页面组件——
Details.vue
<template>
<div class="details">我是详情页</div>
</template>
<script>
export default {
name: "Details",
};
</script>
<style scoped>
.details {
color: rgb(20, 220, 40);
font: italic 700 25px Arial;
}
</style>
- 页面组件——
My.vue
<template>
<div class="my">我是音乐页
</div>
</template>
<script>
export default{
name:"My"
};
</script>
<style scoped>
.my{
color:rgb(20, 159, 113);
font: italic 700 25px Arial;
}
</style>
- 页面组件——
Part.vue
<template>
<div class="part">我是朋友页
</div>
</template>
<script>
export default{
name:"part"
};
</script>
<style scoped>
.part{
color: crimson;
font: italic 700 25px Arial;
}
</style>
- 页面组件——
HelloWorld.vue
<template>
<div class="hello">如果我被App.vue导入,那么我就是App.vue的子组件</div>
</template>
<script>
export default {
name: "HelloWorld",
created() {},
};
</script>
<style scoped>
.hello{
color:cornflowerblue;
font: 700 25px Arial;
}
</style>
- 页面组件——
NotPage.vue
<template>
<div class="NotFound">我是404页</div>
</template>
<script>
export default {
name: "NotFound",
};
</script>
<style scoped>
.NotFound{
color: crimson;
font: normal 900 40px Arial;
}
</style>
二、实现路由跳转2种方式:声明式导航和编程式导航
Vue Router | Vue.js 的官方路由 ◼️ 声明式导航 在浏览器中,点击链接实现导航的方式,叫做声明式导航。例如:普通网页中点击 a标签链接。vue项目中点击router-link标签链接都属于声明式导航。 声明式路由导航,直接写在html中,结构简单使用方便,但是只能放在<router-link>标签中使用,<router-link>标签会将路由转成<a>标签,通过点击跳转路由,因此局限性也非常大。 ◼️ 编程式导航 在浏览器中,调用API方法实现导航的方式,叫做编程式导航。例如:普通网页中调用location.href跳转到新页面的方式,属于编程式导航。vue项目中编程式导航有this.$router.push(),this.$router.replace(),this.$router.go()。 参考资料:Vue路由跳转方式 编程式路由导航,需要写在js中,结构也不算复杂,优势在于非常灵活,不受固定标签限制,可以在任意情景下转跳路由。 实际应用时可根据自身喜好决定使用哪种路由导航方式。
1、声明式导航—router-link
◼️ router-link —声明式路由,在页面中调用—实现跳转最简单的方法
利用组件router-link创建a标签来定义导航链接,它是用来替代a标签的; ◾ router-link 是vue-router提供的一个全局组件; ◾ router-link实质上最终会渲染成a链接,to属性指定目标地址等价于href属性; ◾ router-link提供了声明式导航高亮的功能(自带类名);
1) 不带参数
代码语言:html复制// 注意:router-link中链接如果是'/'开始就是从根路由开始,如果开始不带'/',则从当前路由开始。
// 1. 字符串属性 to ————经测试,以下2种写法都是可以的
<router-link to='/find'> // 字符串
<router-link to='find'> // 字符串
// 2. 动态属性绑定 :to或v-bind:to ————————经测试,以下4种写法都是可以的
// :to="变量或js表达式"
<router-link :to="'find'"> // 不要忘记加引号,字符串也是一个js表达式
// 对象格式,name,path都行, 建议用name
<router-link :to="{name:'find'}">
<router-link :to="{path:'find'}">
<router-link :to="{path:'/find'}">
// 经测试:有component参数时优先router-link中配置的component,没有时从js中配置取
<router-link :to="{path:'/find',component: Find}">
举个栗子:
代码语言:html复制在控制台开发者工具里检查元素时会发现激活的类名,在样式style中有定义高亮样式,点击时就会实现高亮效果
<template>
<div>
<div class="footer_wrap">
// router-link好处 : 自带激活时的类名, 可以做高亮
<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>