什么是前端路由?
路由是根据不同的url地址展示不同的内容或者页面。前端路由就是把不同路由对应不同的内容或者页面的任务交给前端来做,之前是通过服务端根据url的不同返回不同的页面实现的。
什么时候使用前端路由?
在单页面应用,大部分页面结构不变,只改变部分内容的使用。
前端路由的优点和缺点是什么?
- 优点:用户体验好,不需要每次都从服务器全部获取,快速展现给用户
- 缺点:不利于SEO;使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存;单页面无法记住之前滚动的位置,无法在前进和后退的时候记住滚动的位置。
动态路由的实现
动态路由的含义就是url地址中带有参数,这些参数可以自己手动在url上面添加,也可以通过js动态赋值,下面我们在看一下手动在url上面添加的实现
// 路由配置
import Vue from 'vue'
import Router from 'vue-router'
import TestApp from '@/components/TestApp'
import GoodsList from '@/views/GoodsList'
Vue.use(Router)
export default new Router({
routes: [{
path: '/test/:testId/user/:name',
name: 'TestApp',
component: TestApp
}, {
path: '/goods/:goodsId',
name: 'GoodsList',
component: GoodsList
}]
})
// GoodsList组件
<template>
<div class="goods">
<h3>这是商品列表</h3>
<p>获取到的商品id为:{{$route.params.goodsId}}</p>
</div>
</template>
<script>
</script>
<style>
</style>
// TestApp组件
<template>
<div id="app">
<h3>这是测试列表</h3>
<p>获取的id是:{{$route.params.testId}}</p>
<p>获取的名字是:{{$route.params.name}}</p>
</div>
</template>
<script>
</script>
<style>
</style>
// 访问GoodsList组件示例:http://localhost:8080/#/goods/123
// 访问TestApp组件示例:http://localhost:8080/#/test/789/user/jack
为什么路由地址上面一般带有一个#符号?
这是因为路由地址跳转默认(mode)是以哈希方式(hash),可以修改为history方式,这样就不会自动在网址后面加个#符号了
import Vue from 'vue'
import Router from 'vue-router'
import TestApp from '@/components/TestApp'
import GoodsList from '@/views/GoodsList'
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [{
path: '/test/:testId/user/:name',
name: 'TestApp',
component: TestApp
}, {
path: '/goods/:goodsId',
name: 'GoodsList',
component: GoodsList
}]
})
嵌套路由
这个概念挺好理解的,就在路由地址跳转的地方再增加一层子路由跳转,下面请看代码
// 路由设置
import Vue from 'vue'
import Router from 'vue-router'
import GoodsList from '@/views/GoodsList'
import Title from '@/views/Title'
import Image from '@/views/Image'
Vue.use(Router)
export default new Router({
routes: [{
path: '/goods',
name: 'GoodsList',
component: GoodsList,
children: [{
path: 'title',
name: 'Title',
component: Title
}, {
path: 'img',
name: 'Image',
component: Image
}]
}]
})
// GoodsList父组件
<template>
<div class="goods">
<h3>这是商品列表</h3>
<router-link to="/goods/title">显示商品标题</router-link>
<router-link to="/goods/img">显示商品图片</router-link>
<router-view></router-view>
</div>
</template>
<script>
</script>
<style>
</style>
// 其中两个子组件随意加点内容进行区分就好了,在这就不贴代码~
编程式路由
通过JavaScript来实现路由跳转,这种方式在正式的工作中常用,下面请看详细代码
// 路由配置文件
import Vue from 'vue'
import Router from 'vue-router'
import GoodsList from '@/views/GoodsList'
import Cart from '@/views/Cart'
Vue.use(Router)
export default new Router({
routes: [{
path: '/goods',
name: 'GoodsList',
component: GoodsList
}, {
path: '/cart1',
name: 'Cart',
component: Cart
}]
})
// GoodsList组件
<template>
<div class="goods">
<h3>这是商品列表</h3>
<button @click="jump1">第一种跳转到购物车方式</button>
<button @click="jump2">第二种跳转到购物车方式</button>
<button @click="jump3">第三种跳转到购物车方式</button>
<button @click="jump4">第四种跳转到之前的页面</button>
</div>
</template>
<script>
export default {
data() {
return {}
},
methods: {
jump1() {
this.$router.push('/cart1')
},
jump2() {
this.$router.push({
path: '/cart1'
})
},
jump3() {
this.$router.push({
path: '/cart1?goodsId=123'
})
},
jump4() {
// 后退两步
this.$router.go(-2)
}
}
}
</script>
<style>
</style>
当然编程式路由还可以这么来用
this.$router.push({
name: 'ToolCaseList',
params: {
toolcaseId: 'asetting'
}
})
// 配置路由,注意这里不能使用:/toolcaseId来传递参数了,
// 因为父组件中,已经使用params来携带参数了
{
path: "/toolcaselist",
name: "ToolCaseList",
component: ToolCaseList
}
子组件中: 这样来获取参数$route.params.id
命名路由和命名视图
- 命名路由:给路由定义不同的名字,根据名字进行匹配。下面请看具体代码
// 路由配置文件
import Vue from 'vue'
import Router from 'vue-router'
import GoodsList from '@/views/GoodsList'
import Cart from '@/views/Cart'
Vue.use(Router)
export default new Router({
routes: [{
path: '/goods',
name: 'GoodsList',
component: GoodsList
}, {
path: '/cart',
name: 'Cart',
component: Cart
}, {
path: '/cart/:cartId',
name: 'Cart1',
component: Cart
}]
})
// GoodsList组件
<template>
<div class="goods">
<h3>这是商品列表</h3>
<router-link :to="{name:'Cart'}">不传参数跳转到购物车</router-link>
<router-link :to="{name:'Cart1',params:{cartId:123}}">传递参数跳转到购物车</router-link>
</div>
</template>
<script>
</script>
<style>
</style>
// Cart组件
<template>
<div class="cart">
<h3>这是购物车页面</h3>
<p>获取传入过来的参数:{{$route.params.cartId}}</p>
</div>
</template>
<script>
</script>
<style>
</style>
- 给不同的router-view定义名字,通过名字进行对应组件的渲染。下面请看具体代码
// App.vue根组件
<template>
<div id="app">
<router-view></router-view>
<router-view name='title'></router-view>
<router-view name='img'></router-view>
</div>
</template>
<script>
</script>
<style>
</style>
// 路由配置文件
import Vue from 'vue'
import Router from 'vue-router'
import GoodsList from '@/views/GoodsList'
import Title from '@/views/Title'
import Image from '@/views/Image'
import Cart from '@/views/Cart'
Vue.use(Router)
export default new Router({
routes: [{
path: '/',
name: 'GoodsList',
components: {
default: GoodsList,
title: Title,
img: Image
}
}, {
path: '/cart',
name: 'Cart',
component: Cart
}]
})
路由重定向
这个很容易理解,就是当访问某个地址的时候,这个地址又会自动跳转到另一个地址,这就是路由重定向的大白话解释,下面直接看代码就明白是怎么回事了。
import Vue from 'vue'
import Router from 'vue-router'
import Ebook from '@/Ebook'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
redirect: '/ebook'
},
{
path: '/ebook',
name: 'Ebook',
component: Ebook
}
]
})
总结:路由传参的三种基本方式
首先说一下场景:点击父组件某个按钮,跳转到子组件中,并且把对应按钮的id给传递过去,子组件得到该id,然后根据id值的不同来做对应的操作。
下面请看方式一实现:
// 父组件
<ul>
<li v-for="item in list" @click="getData(item.id)"></li>
</ul>
getData(id) {
this.$router.push({
path: `/children/${id}`
})
}
// 路由配置文件
{
path: '/chlidren/:id',
name: 'Children',
component: Children
}
// 子组件
this.$route.params.id
方式二:
// 父组件
<ul>
<li v-for="item in list" @click="getData(item.id)"></li>
</ul>
getData(id) {
this.$router.push({
name: 'Children',
params: {
id: id
}
})
}
// 路由配置文件
{
path: '/chlidren',
name: 'Children',
component: Children
}
// 子组件
this.$route.params.id
方式三:
// 父组件
<ul>
<li v-for="item in list" @click="getData(item.id)"></li>
</ul>
getData(id) {
this.$router.push({
path: '/children',
query: {
id: id
}
})
}
// 路由配置文件
{
path: '/chlidren',
name: 'Children',
component: Children
}
// 子组件
this.$route.query.id
尾声
后面的总结以及路由重定向是在工作中比较常用到的,希望各位童鞋能够掌握了,如有错误,希望指出~