Vue全家桶--10 Vue-Router路由
10.1 什么是路由
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得非常简单。
通过根据不同的请求路径,切换显示不同组件进行渲染页面。
10.2 基本路由使用
10.2.1 安装路由
npm install router" title="vue-router">vue-router
10.2.2 引入 vue-router.js
<script src="./node_modules/vue/dist/vue.js"></script><script src="./node_modules/vue-router/dist/vue-router.js"></script>
10.2.3 HTML 路由切换
<div id="app"><div class="header">
<h1>header</h1>
</div>
<div class="left">
<ul>
<!-- 方式1:传统方式! -->
<li><a href="#/foo">foo</a></li>
<li><a href="#/bar">bar</a></li>
<!-- 方式2:官方推荐! -->
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签, -->
<!-- 通过传入 `to` 属性指定跳转链接,不用像上面加 `#` 号 -->
<li><router-link to="/foo">Go to Foo</router-link></li>
<li><router-link to="/bar">Go to Bar</router-link></li>
</ul>
</div>
<div class="main">
<!-- 路由出口: 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
</div>
</div>
10.2.4 JS 配置路由
<script src="./node_modules/vue/dist/vue.js"></script><script src="./node_modules/vue-router/dist/vue-router.js"></script>
<script>
//1.定义组件
const Foo = {
template:`<div>hello Foo</div>`
};
const Bar ={
template:`<div>hello Bar</div>`
}
// 2. 配置路由表:当点击特定的 url 时,显示对应的那个组件。
const router = new VueRouter({
routes:[ //配置每个路由映射一个组件
{path:'/foo',component:Foo},
{path:'/bar',component:Bar}
]
});
// 3. 注入路由到实例中
new Vue({
el:'#app',
router //router:router
});
</script>
10.3 路由案例实战
10.3.1 修改模板
安装路由/axios
npm install vue-router
npm install axios
10.3.2 News组件
**js函数自调用 ;(function(){})()
**windows 全局属性 window.News={} ,这样就可以全局调用组件,否则在该作用域内,外面无法调用到
;(function(){//
const template=`<!--右边主页面区域-->
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<div class="header clearfix">
<nav>
<ul class="nav nav-pills">
<li class="active"><a href="#">体育</a></li>
<li ><a href="#">科技</a></li>
</ul>
</nav>
<hr>
</div>
<!--体育栏目-->
<div>
<ul>
<li>
<a href="#">世界杯开赛啦</a>
</li>
<li>
<a href="#">NBA开赛倒计时</a>
</li>
</ul>
<!--详情-->
<div class="jumbotron">
<h2>世界杯开赛啦</h2>
<p>世界杯于明晚8点举行开幕式.....</p>
</div>
</div>
<!--科技栏目-->
<div>
<ul >
<li>
<span>5G时代到来了 </span>
<button class="btn btn-default btn-xs">查看(Push)</button>
<button class="btn btn-default btn-xs">查看(replace)</button>
</li>
<li>
<span>互联网大洗牌</span>
<button class="btn btn-default btn-xs">查看(Push)</button>
<button class="btn btn-default btn-xs">查看(replace)</button>
</li>
</ul>
<!--详情-->
<div class="jumbotron">
<h2>世界杯开赛啦</h2>
<p>世界杯于明晚8点举行开幕式.....</p>
</div>
</div>
</div>`;
window.News={
template
}
})()
10.3.3 About组件
; (function () {const template = `<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<h1>梦学谷-陪你学习,伴你梦想!</h1>
<input />
</div>`;
window.About={
template
}
})()
10.3.4 配置路由
新建router.js文件
; (function () {window.router = new VueRouter({
linkActiveClass: 'active',
routes: [
{ path: '/', component: AppHome },
{ path: '/news', component: News },
{ path: '/about', component: About }
]
})
})()
10.3.5 注入路由到实例中
在 main.js 中的 Vue 实例中引入 router
var vm = new Vue({el: '#app',
// Vue实例中的template选项中引用了组件后,会将这个组件的渲染结果替换掉 #app 标签的元素
// template: '<app> </app>',
template:'<app></app>',
router, // 引用路由配置
components:{
App,
}
});
10.3.6 配置路由渲染组件出口
在 App.js 中配置
; (function () {// 组件模板中,必须包含有且只有一个根元素
const template = `
<div>
<!--头部导航区域-->
<app-navbar></app-navbar>
<!--核心区域:分左右两边-->
<div class="container-fluid">
<div class="row">
<!--左边菜单栏区域-->
<app-left></app-left>
<!--右边主页面区域: 分上下两个区域
<app-home>
<h1 slot="dashboard" class="page-header">{{title}}</h1>
</app-home>
-->
<!-- 配置路由渲染组件出口,也就是右边主页面区域 -->
<router-view>
<h1 slot="dashboard" class="page-header">{{title}}</h1>
</router-view>
</div>
</div>
</div>
`;
window.App = {
template,
components: {
AppNavbar,
AppLeft,
AppHome
},
data() {
return {
title: '仪表盘',
};
},
}
})()
10.3.7 修改跳转链接
在 AppLeft.js 中修改跳转链接
; (function () {window.AppLeaf = {
template: `<div class="col-sm-3 col-md-2 sidebar">
<ul class="nav nav-sidebar">
<li class="active">
<router-link to="/">首页</router-link>
</li>
<li>
<router-link to="/news">新闻管理</router-link>
</li>
<li>
<router-link to="/about">关于我们</router-link>
</li>
</ul>
</div>`
}
})()
10.3.8 引入js文件
注意先后顺序
>
<!-- vue-router.js要引入在 vue.js 下方---><script src="../node_modules/vue-router/dist/vue-router.js"></script>
<script src="../node_modules/axios/dist/axios.js"></script>
<script src="./components/AppNavbar.js"></script>
<script src="./components/AppLeft.js"></script>
<script src="./components/Home/DashBoard.js"></script>
<script src="./components/Item.js"></script>
<script src="./components/Home/HomeList.js"></script>
<script src="./components/Home/AppHome.js"></script>
<script src="./components/Home/News.js"></script>
<script src="./components/Home/About.js"></script>
<script src="./router.js"></script>
<script src="./App.js"></script>
<script src="./main.js"></script>
10.3.9 启动测试
http://127.0.0.1:5500/vue-08-router/02-bootstrap-ajax-router/index.html#/
10.4 样式匹配--高亮显示导航
10.4.1 tag
<router-link> 默认渲染后生成 <a> 标签。
可在 <router-link> 上使用 tag 属性,指定渲染后生成其他标签。
10.4.2 active-class
<router-link> 渲染后生成标签上默认有 CSS 类名: router-link-active 。
可在 <router-link> 上使用 active-class 属性,指定渲染后生成其他类名。
可以通过路由的构造选项 linkActiveClass 来全局配置,不用在每个<router-link> 使用 active-class 指定生成
的类名
10.4.3 exact
默认情况 下,路由地址 / 、/foo 、/bar 都以 / 开头,它们都会去匹配 / 地址的 CSS 类名。
可在 <router-link> 上使用 exact 属性开启 CSS 类名精确匹配。
<!-- 这个链接只会在地址为 / 的时候被激活, --><router-link to="/" exact>
10.4.4 实现高亮显示导航链接
AppLeft.js
;(function(){const template=`<div class="col-sm-3 col-md-2 sidebar">
<ul class="nav nav-sidebar">
<!--
router-link 默认渲染出来的是 a 标签,
如果需要让它渲染出来的 是别的标签,则可以使用 tag 属性指定渲染后的标签
2. 可以在每个 router-link 上使用 active-class 来激活 CSS 类名
或者在 VueRouter 实例中,使用 linkActiveClass 全局配置 CSS 类名
3. exact 是精确匹配, 指定在哪个标签上,则这个标签的路径就不会被其他路径模糊匹配
-->
<router-link to="/" tag="li" exact><a>首页</a></router-link>
<router-link to="/news" tag="li"><a>新闻管理</a></router-link>
<router-link to="/about" tag="li"><a>关于我们</a></router-link>
</ul>
</div>`;
window.AppLeft={
template
}
})()
router.js
; (function () {window.router = new VueRouter({
// 全局配置 router-link 标签生成的 CSS 类名
linkActiveClass: 'active',
routes: [
{ path: '/', component: AppHome },
{ path: '/news', component: News },
{ path: '/about', component: About }
]
})
})()
10.5 嵌套路由
10.5.1 子路由组件
10.5.2 配置嵌套路由
{path: '/news',
component: News,
children: [
// 当匹配到 /news/sport 请求时,
// 组件 Sport 会被渲染在 News 组件中的 <router-view> 中
{
path: '/news/sport',
component: Sport
},
// 简写方式,等价于 /news/tech 路径,注意前面没有 / ,有 / 就是根目录了
{
path: 'tech',
component: Tech
},
//点击新闻管理默认选中 新闻,
// 就是/news后面没有子路径时, redirect 重定向到 体育
{
path: '',
redirect: '/news/sport'
}
]
},
10.5.3 路由跳转链接
<ul class="nav nav-pills"><router-link to="/news/sport" tag="li">
<a >体育</a>
</router-link>
<router-link to="/news/tech" tag="li">
<a >科技</a>
</router-link>
</ul>
<!--定义路由出口-->
<router-view></router-view>
10.6 嵌套路由案例--新闻管理
10.6.1 封装路由需要的组件 New组件中的Sport和Tech
Sport.js
; (function () {//
const template = `
<div>
<ul>
<li v-for="(sport,index) in sportArr" :key="sport.id">
<a href="#" >{{ sport.title }}</a>
</li>
</ul>
<!--详情-->
<div class="jumbotron">
<h2>世界杯开赛啦</h2>
<p>世界杯于明晚8点举行开幕式.....</p>
</div>
</div>
`;
window.Sport = {
template,
data() {
return {
sportArr: [],
};
},
created() {
this.getSportArr();
},
methods:{
getSportArr(){
axios.get('http://127.0.0.1:5500/vue-08-router/02-bootstrap-ajax-router/db/sport.json').then(response => {
console.log(response.data) // 得到返回结果数据
this.sportArr = response.data
}).catch(error => {
console.log(error.message)
})
}
}
}
})()
Tech.js
; (function () {//
const template = `
<div>
<ul >
<li v-for="(tech, index) in techArr" :key="tech.id">
<span> {{tech.title}} </span>
<button class="btn btn-default btn-xs">查看(Push)</button>
<button class="btn btn-default btn-xs">查看(replace)</button>
</li>
</ul>
<!--详情-->
<div class="jumbotron">
<h2>世界杯开赛啦</h2>
<p>世界杯于明晚8点举行开幕式.....</p>
</div>
</div>
`;
window.Tech = {
template,
data() {
return {
techArr: [],
};
},
created() {
this.getTechArr();
},
methods: {
getTechArr() {
axios.get('http://127.0.0.1:5500/vue-08-router/02-bootstrap-ajax-router/db/tech.json').then(response => {
console.log(response.data) // 得到返回结果数据
this.techArr = response.data
}).catch(error => {
console.log(error.message)
})
}
}
}
})()
10.6.2 配置嵌套路由
; (function () {window.router = new VueRouter({
// 全局配置 router-link 标签生成的 CSS 类名
linkActiveClass: 'active',
routes: [
{ path: '/', component: AppHome },
{
path: '/news', component: News,
children: [
{
path: '/news/sport', component: Sport
},
{
// 简写方式,等价于 /news/tech 路径,注意前面没有 / ,有 / 就是根目录了
path: 'tech', component: Tech
},
{
//点击新闻管理默认选中 新闻,
//就是/news后面没有子路径时, redirect 重定向到 体育
path: '', redirect: '/news/sport'
}
]
},
{ path: '/about', component: About }
]
})
})()
10.6.3 跳转链接和路由渲染出口
;(function(){//
const template=`<!--右边主页面区域-->
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<div class="header clearfix">
<nav>
<ul class="nav nav-pills">
<router-link to="/news/sport" tag="li" exact><a>体育</a></router-link>
<router-link to="/news/tech" tag="li" exact><a>科技</a></router-link>
</ul>
</nav>
<hr>
</div>
<!--定义路由出口-->
<router-view></router-view>
</div>`;
window.News={
template
}
})()
10.6.4 引入JS
<script src="./components/Home/Sport.js"></script><script src="./components/Home/Tech.js"></script>
10.7 缓存路由组件与案例
10.7.1 场景与作用
1. 默认情况下,当路由组件被切换后组件实例会销毁,当切换回来时实例会重新创建。
2. 如果可以缓存路由组件实例,切换后不用重新加载数据,可以提高用户体验。
10.7.2 实现缓存路由组件
<keep-alive> 可缓存渲染的路由组件实例
<keep-alive><router-view></router-view>
</keep-alive>
10.7.3 demo
上诉的demo中在App.js中添加缓存路由组件
<!-- 配置路由渲染组件出口,也就是右边主页面区域 --><keep-alive>
<router-view>
<h1 slot="dashboard" class="page-header">{{title}}</h1>
</router-view>
</keep-alive>
10.8 路由组件传递数据
10.8.1 路由传递数据步骤
(1)路由配置
{path: '/news/sport',
component: Sport,
children: [
{
path: '/news/sport/detail/:id', // :id 路径变量占位符
component: SportDetail
}
]
}
(2)路由跳转路径
<!--要动态拼接值, 则 to 属性值是 JS 表达式,
要写 JS 表达式, 则要使用 v-bind 方式绑定属性
注意 + 前面有单引号 ''
-->
<router-link :to="'/news/sport/detail/' + sport.id">
{{sport.title}}
</router-link>
(3)在路由组件中读取请求参数
this.$route.params.id
10.8.2 DEMO
配置路由
; (function () {window.router = new VueRouter({
// 全局配置 router-link 标签生成的 CSS 类名
linkActiveClass: 'active',
routes: [
{ path: '/', component: AppHome },
{
path: '/news', component: News,
children: [
{
path: '/news/sport', component: Sport,
children: [
// :id 路径变量占位符
{ path: '/news/sport/detail/:id', component: SportDetail }
]
},
{
// 简写方式,等价于 /news/tech 路径,注意前面没有 / ,有 / 就是根目录了
path: 'tech', component: Tech,
children:[
{path: '/news/tech/detail/:id', component: TechDetail }
]
},
{
//点击新闻管理默认选中 新闻,
//就是/news后面没有子路径时, redirect 重定向到 体育
path: '', redirect: '/news/sport'
}
]
},
{ path: '/about', component: About }
]
})
})()
组件指定路径和渲染出口
; (function () {//
const template = `
<div>
<ul>
<li v-for="(sport,index) in sportArr" :key="sport.id">
<router-link :to="'/news/sport/detail/'+ sport.id" >
{{sport.title}}
</router-link>
</li>
</ul>
<!--详情-->
<!--定义路由出口-->
<router-view></router-view>
</div>
`;
window.Sport = {
template,
data() {
return {
sportArr: [],
};
},
created() {
this.getSportArr();
},
methods:{
getSportArr(){
axios.get('http://127.0.0.1:5500/vue-08-router/02-bootstrap-ajax-router/db/sport.json').then(response => {
console.log(response.data) // 得到返回结果数据
this.sportArr = response.data
}).catch(error => {
console.log(error.message)
})
}
}
}
})()
详情组件
; (function () {const template = `
<div class="jumbotron">
<h2>{{ sportDetail.title }}</h2>
<p>{{ sportDetail.content }}</p>
</div>
`;
window.SportDetail = {
template,
data() {
return {
id: null,
sportDetail: {}
};
},
created() {
// 注意:
// 1. 是 $route , 最后没有 r 字母
// 2. created 钩子只会调用1次,当切换标题列表的路由时,此钩子不会再次调用,
// 所以对应 ID 不会被更新, 可以使用 watch 监听 $route 路由的变化。
this.getItemById();
},
methods: {
getItemById() {
//将路由路径的变量赋值给本地变量
this.id = this.$route.params.id - 0;
var sportItem = [];
axios.get('http://127.0.0.1:5500/vue-08-router/02-bootstrap-ajax-router/db/sport.json').then(response => {
//console.log(response.data) // 得到返回结果数据
sportItem = response.data;
this.sportDetail = sportItem.find(arr => {
return arr.id == this.id;
})
console.log(this.sportDetail);
}).catch(error => {
console.log(error.message);
})
}
},
watch: { // watch 是对象,用于监听属性使用
// 使用 watch 监听 $route 路由的变化,获取 ID 值
'$route': function () {
//console.log('$route');
if ((this.$route.params.id - 0) > 0) { //判断是否是详情页路由
this.getItemById()
}
}
}
}
})()
10.9 编程式路由导航
10.9.1 声明式与编程式路由
**声明式( 直接通过 <a> 标签href指定链接跳转)
<router-link :to="...">
**编程式(采用 js 代码链接跳转,如 localhost.href)
router.push(...)
10.9.2 编程式路由导航 API
this.$router.push(path) 相当于点击路由链接(后退1步,会返回当前路由界面)this.$router.replace(path) 用新路由替换当前路由(后退1步,不可返回到当前路由界面)
this.$router.back() 后退回上一个记录路由
this.$router.go(n) 参数 n 指定步数
this.$router.go(-1) 后退回上一个记录路由
this.$router.go(1) 向前进下一个记录路由
以上是 Vue全家桶--10 Vue-Router路由 的全部内容, 来源链接: utcz.com/z/376519.html