一、什么是路由?
- 路由是通过互联的网络把信息从源地址传输到目的地址的活动
- 路由中有个非常重要的概念叫路由表,本质上就是一个映射表,决定了数据包的指向。
二、什么是前端渲染,什么是后端渲染(服务端渲染)?
(1)后端路由
- 早期网页,用的基本都是后端渲染。当时没有js,用的是(jsp/php),后端渲染对seo优化要好一些,浏览器输入网址,就会把url发到服务器,服务器拿到地址以后,早期会进行一个解析,在后台通过一个jsp的技术,会把网页给你写好,里面包含html和css以及一些java代码。java代码作用就是从数据库读取数据,并且动态的放在页面中,也就是说在浏览器没有呈现页面以前,页面就已经生成了。生成的页面直接传给浏览器,传给浏览器的页面只有html和css,这就是最早期的页面。
- 以上的官方解释就是:
1.早期的网站开发,整个HTML页面是由服务器来渲染的。
2.服务器直接渲染好对应的html页面,返回给客户端展示。
3.一个页面有自己对应的网址,也就是url,url会发送到服务器,服务器会通过正则对该url进行匹配,并且交给一个Controller进行处理。
4.Controller进行各种处理,最终生成HTML或者数据,返回给前端,这就完成了一个I/O操作。
以上这种操作就是后端路由
1.当我们页面中需要请求不同的路径内容时,交给服务器来进行处理,服务器渲染好整个页面,并且将页面返回给客户端,这种情况下渲染好的页面,不需要单独加载任何的js和css,可以直接交给浏览器显示,这样也有利于seo优化。 - 后端路由的缺点:
1.整个页面的模块都需要后端人员编写和维护。
2.前端开发人员如果要开发页面,需要通过php/java等语言来编写页面代码。
3.通常情况下html代码和数据以及对应的逻辑会混在一起,编写和维护都是非常糟糕的事情。
(2)前后端分离阶段
- 这个阶段后端只负责提供数据,不负责任何阶段的内容。
- 随着ajax的出现,有了前后端分离的概念,后端只提供api接口来返回数据,前端通过ajax获取数据,并且可以通过js将数据渲染到页面中。
- 这样做的优点就是前后端责任清晰,后端专注于数据上,前端专注于交互和可视化上。
- 并且当移动端(ios/安卓)出现后,后端不需要进行任何的处理,依然使用之前的一套api即可。目前很多网站依然使用这种模式开发。
(3)单页面富应用阶段
- SPA页面最主要的特点就是在前后端分离的基础上加上了一层前端路由,也就是前端老维护一套路由的规则。
(4)前端路由
- 前端路由的核心是改变url整个页面不刷新。
三、vue-router安装和配置
安装:
npm install vue-router --save
- 在模块化工程中使用它(因为它是一个插件,所以可以通过Vue.use()来安装路由功能)
1.导入路由对象,并且调用Vue.use(VueRouter)
2.创建路由实例,并且转入路由映射配置
3.在Vue实例中挂载创建的路由实例 - 在router文件夹中创建一个index.js,导入
vue-router
1.Vue.use(VueRouter)
const router = new VueRouter({
routes: [] // 路由的映射关系
})
然后我们在main.js中挂载一下router就可以搭好路由的基本配置了,下面我们就可以在routes中设置路由的映射关系了。
- 路由的映射关系:
const routes = [
{
path: '/home',
component: null
},
{
path: '/about',
component: null
}
]
使用vue-router的步骤
1.创建路由组件
2.配置路由映射:组件和路径的映射关系
3.使用路由:通过<router-link>和<router-view>
- router-link 该标签是一个路由内置的组件,会被渲染成a标签。
- router-view 该标签会根据当前的路径,动态渲染出不同的组件
- 网页的其他内容,比如顶部的标题/导航,或者底部的一些版权信息等,会和router-view在同一个等级。
- 在路由切换时,切换的是router-view挂载的组件,其他内容不会发生改变。
路由的默认值改为history模式
- 默认情况下就是hash模式,也就是说在路径中带着#,显得不是很专业。
怎么修改呢?
const router = new VueRouter({
routes: [], // 路由的映射关系
mode: 'history' // 配置这个属性以后,就可以实现把默认的hash模式改为history模式。
})
- 通过上面的配置,此时就会发现路径中不会带有#这样的hash格式了。
router-link补充
- to属性,用于跳转指定的路径
<router-link to='/home'></router-link>
- tag属性,可以指定router-link之后渲染成什么组件,比如下面的代码会被渲染成一个button组件。
<router-link tag='button'></router-link>
- replace属性,replace不会留下history记录,所以指定replace的情况下,后退键返回不能返回到上一个页面中。
<router-link tag='button' replace></router-link>
- active-class属性,当router-link对应的路由匹配成功时,会自动给当前元素一个router-link-active的class,设置active-class可以修改默认名称。
在进行高亮显示的导航菜单或者底部的tabbar时,会使用到该类。
但是通常不会修改该类,会直接使用默认的router-link-active即可。
<router-link tag='button' replace active-class='active'></router-link>
这里也可以全局修改默认的router-link-active类,通过修改路由相关配置文件index.js,增加一个linkActiveClass就可以实现对这个类名称的自定义。
const router = new VueRouter({
routes: [], // 路由的映射关系
mode: 'history',
linkActiveClass: 'active'
})
通过代码跳转路由
- 如果我们不通过router-link的to属性去跳转到指定的路由,那么我们也可以通过js去控制路由的跳转
this.$router.push('/home')
或者this.$router.replace('/home')
,push带有返回按钮
四、动态路由
- 有时候一个页面的path是不确定的,有时候后面会跟着一些参数,这种路径我们称之为动态路由。
const routes = [
{
path: '/home',
component: null
},
{
path: '/about',
component: null
},
{
path: '/user/:id',// 这里的id就是要配置的动态路由
component: null
}
]
- $route指的是当前哪个路由处于活跃状态
this.$route.params.id通过这种方式我们就可以拿到url中的参数值。
- $router指的是我们在入口出new的router对象
五、路由的懒加载
- 当打包构建应用时,js包会变得非常大,影响页面的加载,如果我们能把不同路由对应的组件分成不同的代码块,然后当路由访问时才加载对应组件,这样就比较高效了。这时候就需要用到路由的懒加载。
具体代码写法如下:
const Home = () => import('../components/Home');
const routes = [
{
path: '/home',
component: Home
}
]
六、路由的嵌套
- 嵌套路由是一个很常见的功能,比如我们在home页面中,希望通过/home/news和/home/message访问一些内容
- 一个路径映射一个组件,访问这两个路径,也会分别渲染这两个组件
实现嵌套路由的两个步骤
1.创建对应的子组件,并且在路由映射中配置对应的子路由。
2.在组件内部使用<router-view>标签。
const Home = () => import('../components/Home');
const HomeNews = () => import('../components/HomeNews');
const HomeMessage = () => import('../components/HomeMessage ');
const routes = [
{
path: '/home',
component: Home,
children: [
{
path: '',
redirect: 'news'// 默认显示新闻页
},
{
path: 'news',
component: HomeNews
},
{
path: 'message',
component: HomeMessage
}
]
}
]
七、路由参数传递
- 传递路由有两种方式:params和query
1.params类型:
(1)配置路由格式:/router/:id
(2)传递方式:在path后面跟上对应的值
(3)传递后形成的路径:/router/123,/router/abc
const routes = [
{
path: '/profile:id',
component: 'Profile'
}
]
页面中取出某个参数:$route.params.id
2.query类型:
(1)配置路由格式:/router,也就是普通的配置
(2)传递的方式:对象中使用query的key作为传递方式
(3)传递后的路径:/router?id=123
<router-link :to={ path: '/router', query: { name: 'aaa', age: 18 }}></router-link>
页面中取出某个参数:$route.query.name
3.通过点击事件实现路由传递参数
methods: {
// params方式
userClick () {
this.$router.push('/user/' + this.userId)
},
// query 方式
proFileClick () {
this.$router.push({
path:'/profile',
query: {
name: 'kobe',
age: 18
}
})
},
}
4.$route
和 $router
的区别
-
$route
指的是当前活跃的路由,$router
指的是路由本身,里面包含了很多方法。 - 所有的组件都继承自vue的原型
八、vue-router的全局导航守卫
- 全局守卫
- 意思就是对路由来回跳转的时候进行一些监听,在跳转的过程中有可能要做其他的事情。
- 以下代码实现的是页面跳转变换页面对应的title:
router.beforeEach((to, from, next) => {
// beforeEach叫做前置守卫(hook)
// meta 元数据(描述数据的数据)
document.title = to.matched[0].meta.title;
next('/login')
// next可用于判断是否登录,没有登录直接跳转到登录页面
})
导航钩子的三个参数解析:
-
to
:即将要进入的目标的路由对象 -
from
:当前导航即将要离开的路由对象 -
next
: 调用该方法后,才能进入下一个钩子
补充:
-
afterEach()
后置守卫,路由跳转结束后要做的一些事情。
router.afterEach((to, from) => {
console.log('aaa');
})
- 路由独享守卫
- 组件内守卫
九、keep-alive以及其他问题
- keep-alive 是Vue内置的一个组件,可以使被包含的组件保留状态,或者避免重新渲染。
<keep-alive>
<roouter-view />
</keep-alive>
- keep-alive有两个重要的属性:
1.include - 字符串或者正则表达,只有匹配的组件才会被缓存
2.exclude - 字符串或者正则表达,任何匹配的组件都不会被缓存
<keep-alive exclude='Profile,User'>
// 上面两个组件之间最好不要加空格,会出现问题
<roouter-view />
</keep-alive>
activated/deactivated只有在页面使用了keep-alive保持状态的时候才会起作用
注:
const router = new VueRouter({
routes,
mode: 'histroy',
// 这里使用history模式,代替hash模式,这样的话在路径中就不会出现类似hash的路径格式。
})