初见前端路由和Vue rouuter
什么是router(路由)
路由:就是通过互联的网络把信息从源地址传输到目的地址的活动--维基百科
- 那生活中什么是路由?
-
路由器
就是生活中路由
的的实际体现 -
路由器提供了
两种机制
:路由和传送- 路由决定了数据包从
来源
到目的地
路径 - 转送将
输入端
的数据转移到合适的输出端
- 路由决定了数据包从
-
那路由中还有一个重要的
概念
:路由表- 路由表
本质
上是一个映射表
,决定了数据包的指向。
- 路由表
-
那么开发中路由是怎样使用的呢?
- 后端路由阶段
-
最开始的时候其实路由的概念是起源于
后端
也就是服务器端,在 早期前后端还没有分离
的时候,服务器是直接将渲染好的HTML页 面,返回给客户端进行展示,没有太多前端的事。。。 -
那么一个网站网页这么多,服务器是如何如何处理的呢?
- 每个页面都有自己对应的网址,也就是
URL
URL
发送给服务器,服务器会通过URL进行匹配,并且交给Controller
进行处理。这也就是后端路由
。- 服务器端再将对应的
HTML或者数据
返回给前端。
- 每个页面都有自己对应的网址,也就是
-
后端路由的
好处
:- 安全性好,
SEO
好
- 安全性好,
-
后端路由的
缺点
:- 加大服务器压力,不利用用户体验,代码耦合不利于维护
-
- 前端路由阶段
-
随着
Ajax
的出现,就有了前后端分离
的模式。此时的后端只提供API来返回数据,前端通过Ajax
获取数据,并且通过JavaScript将数据渲染到页面上--这也就是所谓的前端渲染
。
-
但是虽然
Ajax
虽然解决了用户交互时体验的痛点,但是多页面间的跳转一样会有不好的体验,所以就有了spa(single-page application)
的使用,而spa应用是基于前端路由实现,所以就有了前端路由。
-
什么是前端路由?
- 在
spa
中,路由描述的是URL
和UI
之间的映射关系,这种映射关系是单向的,即URL变化引起的UI更新
(无需刷新页面)
如何实现前端路由
-
Hash
模式原理:- 早期的前端路由基于
loaction.hash
来实现,location.hash(值)
种的值就是url
中#
后面的内容。比如:👇
https://www.localhost/#/search
- hash方法有几个
特性
:-
URL
中hash
是客户端中的一种状态,也就是说当向服务器发出请求时,hash
不会被发送 -
hash
值被改变都会在访问历史中加一个记录
,也就是说我们可以通过浏览器实现前进
和后退
-
- 早期的前端路由基于
-
HTML5
中history
原理:-
HTML5的的
History API
为浏览器的全局history对象添加了扩展方法。 -
我们主要使用两个方法进行
改变url
:history.pushState()
:会在浏览器中留下历史记录
history.repalceState()
:不会
再浏览器中留下历史记录
-
-
两者区别:
对比 Hash History 观赏性 相对丑 相对美 兼容兼容性 >ie8 >ie10 实用性 直接使用 需后端配合
认识Vue-router
-
什么是Vue-router
vue-router时Vue.js官方的路由插件,它和Vue.js时深度集成的,适用于构建单页面应用。vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。
-
Vue-router
是基于路由
和组件
的-
路由
用于设定访问路径,将路径和组件映射起来 -
在
vue-router
的单页面应用中,页面的路径的改变就是组件的切换
-
-
安装和使用
vue-router
- 安装vue-router
npm install vue-router --save
- 在模块化工程中使用它(因为是一个插件,所以通过Vue.use()来安装路由功能)
-
导入路由对象,并且调用
Vue.use(Router)
-
创建
路由实例
,并且传入映射配置
-
在
Vue实例
中挂在创建的路由实例
// 1.通过Vue.use(插件), 安装插件 Vue.use(VueRouter) // 2.创建VueRouter对象,配置路由映射关系 const routes = [ { path: '', // redirect重定向 redirect: '/home' }, { path: '/home', component: Home }, { path: '/about', component: About } ] const router = new VueRouter({ // 配置路由和组件之间的应用关系 routes, //使用路由的方式 mode: 'history', })
-
- 使用路由:
- 我们可以使用
<router-link>
来在Vue组件
中使用
<!-- 1.第一种使用路由方式 --> <!-- to:所转的路径 --> <!-- tag:所需要渲染出来的标签 --> <!-- replace:取消转换路径时的历史记录 --> <router-link to="/home" tag="button" replace>首页</router-link> <router-link to="/about" tag="button" replace>关于</router-link> <!-- 2. 第二种使用路由的方式,自定义事件 --> <button @click="homeClick">首页</button> <button @click="aboutClick">关于</button>
- 我们可以使用
动态路由
-
有时候我们需要动态的对路由进行配置,例如:当进入不同用户的界面时,需要动态的获取用户的id对路由进行配置。
-
步骤:
- 对
router
中index.js
的路路径进行动态配置 - 在
App.vue
中对:to
进行传值。 - 在
组件中
调用
//步骤一: { path: '/', name: 'about:user', component: About }, //步骤二: <router-link :to="'/about'+userId">About</router-link> <script> export default { name:"App", data(){ return{ userId:'zhangsan' } } } </script> //步骤三: export default { name:"About", computed:{ userId(){ //对当前路由的 return this.$route.params.user } } }
- 对
路由懒加载
当打包构建应用时,Javascript 包会变得非常大,影响页面加载。
如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了
-
路由懒加载主要做了什么?
- 路由懒加载主要作用时将路由对应的组件打包成一个个的
js
代码块 - 只有在路由被访问的时候,才加载对应的组件
- 路由懒加载主要作用时将路由对应的组件打包成一个个的
-
路由懒加载后的效果
-
路由懒加载
前
:
-
路由懒加载
后
:
-
-
可以看出来路由懒加载后,由之前的三个基础组件,增加了
模板组件
打包后的文件 -
路由懒加载的方式
- 方式一:结合Vue的异步组件和webpack的代码
const Home = resolve => { require.ensure(['../components/Home.vue'], () => { resolve(require('../components/Home.vue')) })};
- 方式二:AMD写法
const About = resolve => require(['../components/About.vue'], resolve);
- 方式三:ES6写法,更简单更方便
目前用的最多
const Home = () => import('../components/Home.vue')
- 方式一:结合Vue的异步组件和webpack的代码
Vue-router 传递参数
-
主要步骤
- 创建
新的组件
- 配置路由
映射
- 添加跳转的
<router-link>
- 创建
-
主要由两种传递参数的方式
params
的类型
- 配置路由格式: /router/:id
- 传递的方式: 在path后面跟上对应的值
- 传递后形成的路径: /router/123, /router/abc
query
的类型
- 配置路由格式: /router, 也就是普通配置
- 传递的方式: 对象中使用query的key作为传递方式
- 传递后形成的路径: /router?id=123, /router?id=abc
-
query
方式的两种形式//直接在router-link以对象的形式来传递参数 <router-link :to="{path: '/profile', query: {name: 'why', age: 18, height: 1.88}}"> //自定义事件来传递参数 profileClick() { this.$router.push({ path: '/profile', query: { name: 'kobe', age: 19, height: 1.87 } }) //获取参数 <h2>{{$route.query.age}}</h2>
-
$router
和$route
的区别$router
为VueRouter实例,想要导航到不同URL
,则使用$router.push方法$route
为当前router跳转对象里面可以获取
name、path、query、params等
导航守卫
-
什么是导航守卫?
正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。--官网
- vue-router提供的导航守卫主要用来监听监听路由的进入和离开的.
- vue-router提供了
beforeEach
和afterEach
的钩子函数, 它们会在路由即将改变前和改变后触发.
-
为什么使用导航守卫
- 试想我们有这样一个需求:在SPA的应用中,如何改变每个
单页的标题
呢?- 这种情况下,如果没有导航守卫,我们可能会采用
mouted
声明周期函数来对document.title
进行修改
- 这种情况下,如果没有导航守卫,我们可能会采用
- 但如果有了导航守卫,我们可以更方便的使用
导航守卫
来对title
进行修改
- 试想我们有这样一个需求:在SPA的应用中,如何改变每个
-
解析导航函数的简单使用
- 我们需要使用
beforeEach
来完成标题修改,需要两个步骤:- 在
路由
中我们可以使用meta
来定义title
的名字 - 利用
导航守卫
,我们可以修改我们的标题
//步骤一: { path: '/home', component: Home, meta: { title: '首页' } //步骤二: // 前置守卫(guard) router.beforeEach((to, from, next) => { // 从from跳转到to document.title = to.matched[0].meta.title next() })
- 在
- 导航钩子的三个参数解析:
to
: 即将要进入的目标的路由对象.from
: 当前导航即将要离开的路由对象.next
: 调用该方法后, 才能进入下一个钩子.
- 我们需要使用
keep-alive 和 vue-router
-
keep-alive
是 Vue 内置的一个组件,用于使被包含的组件保留状态,避免重新渲染. -
在学习之前需要懂得
Vue
的生命周期
-
步骤:
- 将要显示的组件用
<keep-alive>
- 在对应的组件里,可以使用对应的方法了
//步骤一: <keep-alive exclude="Profile,User"> <router-view/> </keep-alive> // 以下, 只有该组件被保持了状态使用了keep-alive时, 才是有效的 activated() { this.$router.push(this.path); console.log('activated'); }, deactivated() { console.log('deactivated'); }, beforeRouteLeave (to, from, next) { console.log(this.$route.path); this.path = this.$route.path; next() }
- 将要显示的组件用