- 什么是路由?
1、后端路由:早期会通过解析不同的URL,服务器找到对应的资源,并渲染成页面,最后将对应的页面返回给客户端直接展示。
2、前端路由:前后端分离后,可以先通过静态资源服务器拿到HTML+CSS+JS文件,然后在进入不同页面的时候使用Ajax获取API服务器上的数据资源,这样最大的优点就是前后端责任清晰,后端专注于数据,前端专注于可视化,服务器压力也比较小。
3、前端路由/SPA:
a、首先,对于单页面应用程序整个项目只有一个HTML,用户一开始就获取整个项目静态资源。
b、SPA是在前端路由的基础上又增加了一层前端路由,通过监测href的数据来切换不同的组件,切换到的组件发起Ajax请求,最后在API服务器上拿到数据资源,看起来就像进入了新页面一样。
c、vue-router是通过hash来修改href并可以做到不刷新页面。(href是一个栈储存,先进后出)
备注:URL:
协议:// 主机:端口/路径?查询#哈希
scheme:// host:port/path?query#fragment
location.hash = '/home'
history.pushState({},'','/home') // HTML提供的方法
history.go(-1) // 复数后退,正数为前进,数字带表步数
- 具体的使用方法:
// 安装vue-router,并新建文件夹router->index.js
npm install vue-router --save
在index.js中配置路由项
import Vue from 'vue'
import VueRouter from 'vue-router'
import about from '@/components/about'
import home from '@/components/home'
use(VueRouter) // 安装注入插件
routes = [
{
path: '/',
name: 'home',
component: home,
redirect: '/home' // 重定向
meta: { // 元数据(描述数据的数据)
title: '首页'
},
beforeEach: (to, form, next) => {}, // 路由独享守卫
children: [ // 嵌套子路由
{
path: '/',
component: isMessage
},
{
path: 'isMessage',
component: isMessage
},
{
path: 'isNew',
component: isNew
}
]
},
{
path: '/about/:aboutId', // 动态绑定路由
component: about,
meta: {
title: '关于'
},
},
{
path: '/shopList',
component: shopList,
meta: {
title: '商品',
},
}
]
// 创建router实例
const router = new VueRouter({
routes
})
// 前置守卫(guard)
router.beforeEach((to, form, next) => {
window.document.title = to.matched[0].meta.title // 修改每个页面的标题
next() // 必须调用,否则不生效
})
// 后置钩子(hook)
router.afterEach((to, form) => {
console.log(to)
})
export default router // 导出实例
挂载到vue实例
// 在main.js中
import router from './router' // 导入
new Vue({
el: ''#app',
router,
render: h => h(App)
})
路由跳转
<router-link to="/home" tag="button" replace>按钮</router-link>
// tag指定渲染成什么样的标签,replace不会在history中留下记录,无法回退
this.$router.push('/home')
this.$router.replace('/home') // 无痕浏览
this.$router.go('/home') // 接受一个整数作为参数,在 history 记录中向前后多少步
<router-link :to="'/about/'+aboutData" tag="button">关于</router-link>
// 动态页面的跳转aboutData在data中定义
<h3>{{$route.params.aboutId}}</h3>
// 在about页面中用可以拿到在动态的URL
<keep-alive exclude='about'>
// exclude排除某个路由不缓存,include为缓存,使用页面name属性标记,多个状态用逗号且不能使用空格
// 路由来回跳转时,保持页面不更新
<router-view/>
</keep-alive>
activated () { // 活跃状态执行函数
this.$router.push(this.path) // 在活跃状态的时候直接进入到需要展示的路由
},
deactivated() { // 非活跃状态执行函数
console.log('deactivated')
},
// 以上两个函数必须适应keep-alive才会有效
beforeRouteLeave (to, from, next) {
this.path = this.$route.path // 离开页面的时候记录下用户选择的路由
next()
}
嵌套路由
<router-link to='/home/isMessage'>消息</router-link>
<router-link to='/home/isNew'>新闻</router-link>
<router-view/>
路由的懒加载:js的静态资源按组件分包,用到时再发送请求
// import about from '@/components/about'
// import home from '@/components/home'
const about = () => import('@/components/about')
const home = () => import('@/components/home')
路由传参
<router-link :to="{path:'/shopList',query:{userId: '9527'}}" tag="button"></router-link> // 传参
<h3>{{$route.query.userId}}</h3> // 接收参数
// 函数跳转
<button @click="listClick">商品</button>
listClick () {
this.$router.push({
path: '/shopList',
query: {
name: 'word'
}
})}
<h3>{{$route.query.name}}</h3> // 接收参数
组件内守卫
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
网友评论