路由
实现 spa应用(single page application)
优点:
1.、整个应用只有一个 html文件,所以的 路由对应页面都是由组件来实现
2、在切换路由 时 不需要 重新加载 页面 只需要切换组件即可(切换效率较高)
缺点:
因为代码都在js中,html源码基本看不到内容,seo爬虫爬取的时html源码,不会爬取js中的内容 对于seo不友好
相对应的是(mpa multiple page application 多页面应用)
路由基础配置
语法如下
const Home = {
template: `
<div>
<h1> home页 </h1>
</div>
`
}
const News = {
template: `
<div>
<h1> 新闻页 </h1>
</div>
`
}
const About = {
template: `
<div>
<h1> 关于我们页 </h1>
</div>
`
}
// 名字必须是routes
const routes = [
{
path: '/home',
component: Home
},
{
path: '/news',
component: News
},
{
path: '/about',
component: About
}
]
// 定义路由对象
const router = new VueRouter({
routes
})
// 最后一步 定义出口
<router-view />
// 组件用于跳转路由的
<router-link
to="/home"
tag="button"
>首页</router-link>
new Vue({
el: '#app',
router: router
})
demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../../vue.js"></script>
<script src="./vue-router.js"></script>
<style>
*{
margin: 0;
padding: 0;
}
#navgation{
position: absolute;
bottom: 0;
width: 100%;
height: 30px;
font-size: 18px;
background-color: aquamarine;
display: flex;
justify-content: space-around;
}
#navgation>a{
text-decoration: none;
width: 30%;
text-align: center;
}
</style>
</head>
<body>
<div id="app">
<div id="navgation">
<router-link to="/home">主页</router-link>
<router-link to="/news">新闻</router-link>
<router-link to="/user">我的</router-link>
</div>
<h1>这是主页面</h1>
<router-view></router-view>
</div>
</body>
<script>
const Home = {
template: `
<div>
<h1>home页</h1>
</div>
`
}
const News = {
template: `
<div>
<h1>news页</h1>
</div>
`
}
const User = {
template: `
<div>
<h1>user页</h1>
</div>
`
}
// 以上为路由组件,需要在路由配置中挂载
// 定义路由
const routes = [
// 路由规则
{
path: '/home',
component: Home
},
{
path: '/news',
component: News
},
{
path: '/user',
component: User
},
]
const router = new VueRouter({
routes
})
const vm = new Vue({
el: '#app',
router: router,
})
</script>
</html>
运行结果
处理路由的根路径
我们可以发现上述的代码在第一次运行时,打开的页面不在主页上,没有加载我们的组件,这是因为我们没有为根路径设置指向,这里我们有2种方法可以解决
// 注意,这里必须是routes不能改变
const routes = [
// 方法1
{
path: '/',
component: Home
}, // 不推荐
// 方法2
{
path: '/',
redirect: '/home' // 推荐重定向
},
{
path: '/home',
component: Home
}
]
处理404,路径错误
在我们平时浏览网页是经常会遇到404错误,这是因为我们的路径错误,无法获取到内容这里我们就可以对404做这样的处理
const NotFound = {
template: `
<div>
<center>
<h1>404</h1>
<h3>无法请求到页面</h3>
</center>
</div>
`,
}
const routes = [
// 定义路由规则
//重定向 '/' 路径指向
{
path: '/',
redirect: '/news'
},
{
path: '/news/:id',
component: News
},
{
path: '*',
component: NotFound
}
]
注意这里的路径使用 * 号指任意路径,所以一定要放在所有路由的最后面,这样除了我们自己定义的路由,所有其他的路由都会跳转到404页面上去了
{
path: '*', // 匹配任意地址
component: NotFound
}
动态路由
我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 news
组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router
的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果:
const News = {
template: `
<div>
<h1>新闻{{ $route.params.id }}页</h1>
</div>
`,
methods: {
fetchData () {
console.log(this.$route);
}
},
watch: {
$route () {
console.log(12);
this.fetchData()
}
}
}
// 定义路由
const routes = [
// 定义路由规则
//重定向 '/' 路径指向
{
path: '/',
redirect: '/news'
},
{
path: '/news/:id',
component: News
},
{
path: '*',
component: NotFound
}
]
const router = new VueRouter({
routes
})
在目标路由组件中 Detail this.$route.params.id 获取
注意:
$route对象 是 引入vue-router 自动 往Vue构造函数 的原型上 灌入的 一个对象,这个对象保存了 当前路由的 基本信息 如 路由地址、路由名字、元信息、参数....
// 监听动态路由参数的变化
{
watch:{
$route(){
// 只要参数变化 这个侦听器函数 就会调用,在这里可以重新获取数据
}
}
}
整体代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../../vue.js"></script>
<script src="./vue-router.js"></script>
<style>
*{
margin: 0;
padding: 0;
}
#navgation{
position: absolute;
bottom: 0;
width: 100%;
height: 30px;
font-size: 18px;
background-color: rgba(127, 255, 212,0.5);
display: flex;
justify-content: space-around;
}
#navgation>a{
text-decoration: none;
width: 30%;
text-align: center;
}
#navgation .router-link-active{
background-color: rgba(127, 255, 212, 1);
color: seagreen;
}
</style>
</head>
<body>
<div id="app">
<div id="navgation">
<router-link to="/news/1">新闻1</router-link>
<router-link to="/news/2">新闻2</router-link>
<router-link to="/news/3">新闻3</router-link>
<router-link to="/news/4">新闻4</router-link>
</div>
<router-view></router-view>
</div>
</body>
<script>
const News = {
template: `
<div>
<h1>新闻{{ $route.params.id }}页</h1>
</div>
`,
methods: {
fetchData () {
console.log(this.$route);
}
},
watch: {
$route () {
console.log(12);
this.fetchData()
}
}
}
const NotFound = {
template: `
<div>
<center>
<h1>404</h1>
<h3>无法请求到页面</h3>
</center>
</div>
`,
}
// 定义路由
const routes = [
// 定义路由规则
//重定向 '/' 路径指向
{
path: '/',
redirect: '/news'
},
{
path: '/news/:id',
component: News
},
{
path: '*',
component: NotFound
}
]
const router = new VueRouter({
routes
})
const vm = new Vue({
el: '#app',
router
})
</script>
</html>
路由的嵌套
实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件,
借助 vue-router
,使用嵌套路由配置,就可以很简单地表达这种关系。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../../vue.js"></script>
<script src="./vue-router.js"></script>
<style>
*{
margin: 0;
padding: 0;
}
#navgation{
position: absolute;
bottom: 0;
width: 100%;
height: 30px;
font-size: 18px;
background-color: rgba(127, 255, 212,0.5);
display: flex;
justify-content: space-around;
}
#navgation>a{
text-decoration: none;
width: 30%;
text-align: center;
}
#navgation .router-link-active{
background-color: rgba(127, 255, 212, 1);
color: seagreen;
}
.router-link-active{
color: steelblue;
}
</style>
</head>
<body>
<div id="app">
<div id="navgation" >
<router-link to="/home" >主页</router-link>
<router-link to="/news" >新闻</router-link>
<router-link to="/user" >我的</router-link>
</div>
<router-view></router-view>
</div>
</body>
<script>
const Home = {
template: `
<div>
<h1>home页</h1>
</div>
`
}
const News = {
template: `
<div>
<h1>news页</h1>
<router-link to='/news/native'>国内新闻</router-link>
<router-link to='/news/foreign'>国外新闻</router-link>
<router-view></router-view>
</div>
`
}
// 定义News中的子组件
const NativeNews = {
template: `
<div>
<h3>国内新闻</h3>
</div>
`
}
const ForeignNews = {
template: `
<div>
<h3>国外新闻</h3>
</div>
`
}
const User = {
template: `
<div>
<h1>user页</h1>
</div>
`
}
const NotFound = {
template: `
<div>
<center>
<h1>404</h1>
<h3>无法请求到页面</h3>
</center>
</div>
`,
}
// 以上为路由组件,需要在路由配置中挂载
// 定义路由
const routes = [
// 路由规则
{
path:'/',
redirect:'/home'
},
{
path: '/home',
component: Home
},
{
path: '/news',
component: News,
children:[
{
path: '/news/',
component: NativeNews
},
{
path: '/news/native',
component: NativeNews
},
{
path: '/news/foreign',
component: ForeignNews
}
]
},
{
path: '/user',
component: User
},
{
path: '*',
component: NotFound
}
]
const router = new VueRouter({
routes
})
const vm = new Vue({
el: '#app',
router: router,
})
</script>
</html>
命名路由
有时候,通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由,或者是执行一些跳转的时候。你可以在创建 Router 实例的时候,在 routes
配置中给某个路由设置名称。
参数获取 this.$route.params.xxx
优点: 隐式传参
缺点: 刷新后丢失
注意:
name和params是固定搭配
path和params搭配无法传参的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../../vue.js"></script>
<script src="./vue-router.js"></script>
<style>
*{
margin: 0;
padding: 0;
}
#navgation{
position: absolute;
bottom: 0;
width: 100%;
height: 30px;
font-size: 18px;
background-color: rgba(127, 255, 212,0.5);
display: flex;
justify-content: space-around;
}
#navgation>a{
text-decoration: none;
width: 30%;
text-align: center;
}
#navgation .router-link-active{
background-color: rgba(127, 255, 212, 1);
color: seagreen;
}
.router-link-active{
color: steelblue;
}
</style>
</head>
<body>
<div id="app">
<div id="navgation" >
<router-link :to="{
name: '首页',
params: {
a:10,
b:20
}
}" >主页</router-link>
<router-link :to="{name: '新闻'}" >新闻</router-link>
<router-link :to="{name: '我的'}" >我的</router-link>
</div>
<router-view></router-view>
</div>
</body>
<script>
const Home = {
template: `
<div>
<h1>home页</h1>
</div>
`
}
const News = {
template: `
<div>
<h1>news页</h1>
<router-link to='/news/native'>国内新闻</router-link>
<router-link to='/news/foreign'>国外新闻</router-link>
<router-view></router-view>
</div>
`
}
// 定义News中的子组件
const NativeNews = {
template: `
<div>
<h3>国内新闻</h3>
</div>
`
}
const ForeignNews = {
template: `
<div>
<h3>国外新闻</h3>
</div>
`
}
const User = {
template: `
<div>
<h1>user页</h1>
</div>
`
}
const NotFound = {
template: `
<div>
<center>
<h1>404</h1>
<h3>无法请求到页面</h3>
</center>
</div>
`,
}
// 以上为路由组件,需要在路由配置中挂载
// 定义路由
const routes = [
// 路由规则
{
path:'/',
redirect:'/home'
},
{
path: '/home',
name: '首页',
component: Home
},
{
path: '/news',
name: '新闻',
component: News,
children:[
{
path: '/news/',
component: NativeNews
},
{
path: '/news/native',
component: NativeNews
},
{
path: '/news/foreign',
component: ForeignNews
}
]
},
{
path: '/user',
name: '我的',
component: User
},
{
path: '*',
name: '404无法查询',
component: NotFound
}
]
const router = new VueRouter({
routes
})
const vm = new Vue({
el: '#app',
router: router,
})
</script>
</html>
理由query传参
利用query传参时,会将参数渲染到url上去
优点:刷新不丢失
缺点:在地址栏上直接显示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../../vue.js"></script>
<script src="./vue-router.js"></script>
<style>
*{
margin: 0;
padding: 0;
}
#navgation{
position: absolute;
bottom: 0;
width: 100%;
height: 30px;
font-size: 18px;
background-color: rgba(127, 255, 212,0.5);
display: flex;
justify-content: space-around;
}
#navgation>a{
text-decoration: none;
width: 30%;
text-align: center;
}
#navgation .router-link-active{
background-color: rgba(127, 255, 212, 1);
color: seagreen;
}
.router-link-active{
color: steelblue;
}
</style>
</head>
<body>
<div id="app">
<div id="navgation" >
<router-link :to="{
path: '/home',
query: {
a:10,
b:20
}
}" >主页</router-link>
<router-link :to="{
path: '/news',
query: {
c:30,
d:40
}
}" >新闻</router-link>
<router-link :to="{path: '/user'}" >我的</router-link>
</div>
<router-view></router-view>
</div>
</body>
<script>
const Home = {
template: `
<div>
<h1>home页</h1>
</div>
`
}
const News = {
template: `
<div>
<h1>news页</h1>
<router-link to='/news/native'>国内新闻</router-link>
<router-link to='/news/foreign'>国外新闻</router-link>
<router-view></router-view>
</div>
`
}
// 定义News中的子组件
const NativeNews = {
template: `
<div>
<h3>国内新闻</h3>
</div>
`
}
const ForeignNews = {
template: `
<div>
<h3>国外新闻</h3>
</div>
`
}
const User = {
template: `
<div>
<h1>user页</h1>
</div>
`
}
const NotFound = {
template: `
<div>
<center>
<h1>404</h1>
<h3>无法请求到页面</h3>
</center>
</div>
`,
}
// 以上为路由组件,需要在路由配置中挂载
// 定义路由
const routes = [
// 路由规则
{
path:'/',
redirect:'/home'
},
{
path: '/home',
name: '首页',
component: Home
},
{
path: '/news',
name: '新闻',
component: News,
children:[
{
path: '/news/',
component: NativeNews
},
{
path: '/news/native',
component: NativeNews
},
{
path: '/news/foreign',
component: ForeignNews
}
]
},
{
path: '/user',
name: '我的',
component: User
},
{
path: '*',
name: '404无法查询',
component: NotFound
}
]
const router = new VueRouter({
routes
})
const vm = new Vue({
el: '#app',
router: router,
})
</script>
</html>
总结:vue路由跳转传参的方式有
1,动态路由
2,name+params传参
3,path+query