路由是什么?为什么要使用路由?路由有什么功能?可以写出路由跳转的源码吗?
写完路由部分,四连打击让我深思,一起来学习一下vue的翅膀Vue-Router吧~
这是一个基于 vue & axios & mock & token & stylus & Cube-UI的电商项目demo,面向 vue 初学者,场景虽简单,但五脏俱全。涵盖非常多的vue及其相关技术的基本操作。有详细的注释,帮助大家快速上手 vue 。
Github地址
- vue-jingdong (不要吝惜你的小星星哦)
- 话不多说上效果图
正文部分
作为VUE的初学者,创建一个项目后的demo里面就有home页面和about页面的跳转。在写这个小项目的时候,我也是照葫芦画瓢没有过多的思考。写完路由部分的时候,反过来思考,心中也有许多疑问。路由是什么?为什么要使用路由?路由有什么功能?可以写出路由跳转的源码吗?
带着这些问题我查阅了很多资料和文章,发现它们都比较散,往往只讲述一个小点。如果你也有相同的问题就跟随我来逐一击破吧~
路由是什么?
- 路由:即浏览器中的哈希值(# hash)与展示视图内容(template)之间的对应规则。
在计算机网络原理中,路由指的是根据上一接口的数据包中的IP地址,查询路由表转发到另一个接口,它是决定一个端到端的网络路径。所以说路由就是用来解析URL以及调用对应的控制器的。
- vue中的路由是:hash 和component的对应关系。Vue路由即vue-router,在web开发中,“router”是指根据url分配到对应的处理程序。
通俗的来说,在web开发中,路由就是一套映射规则(一对一的对应规则),由开发人员制定规则。
当URL中的哈希值(# hash)发生改变后,路由会根据制定好的规则,展示对应的视图内容。
为什么要使用路由?
在传统的web开发中每一个请求地址都会请求服务器来进行处理,但是用户有些操作则无需请求服务器,直接页面端修改下逻辑就能达到目的,在这种方式下最好的方法是使用路由,因为使用路由时,URL会随着改变,用户浏览一个网页时可以直接复制或收藏当前页面的URL给别人,这种方式对于搜索引擎和用户来说都是友好的。
在 Web app 中,通过一个页面来展示和管理整个应用的功能。
SPA(单页应用程序)往往是功能复杂的应用,为了有效管理所有视图内容,前端路由 应运而生!
路由有什么功能?
这个问题,我是通过Vue Router开发者文档,进行了解的,但是我看完之后还是有点懵懵懂懂,没有特别理解,之后我是通过查阅一些文章对路由的功能有了更深入的了解,下面跟随作者一起结合项目来看看吧~
- vue router文档 (这篇文章我就介绍其中的几个功能,其他的可以去看看哈)
基本使用
安装:npm i -S vue-router或者创建vue项目时就选择了router
// 3 创建两个组件 作者就不写代码啦vue项目一开始的demo有创建。
//router中的index.js
import Register from '../views/Register.vue'
import Login from '../views/Login.vue'
Vue.use(VueRouter)
// 4 创建路由对象
const routes = [
{
path: '/',
name: 'login',
redirect: '/login'
},
// 路径和组件一一对应
{
path: '/register',
name: 'register',
component: Register
},
{
path: '/login',
name: 'login',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
//项目路由懒加载,秒开
component: () => import(/* webpackChunkName: "about" */ '../views/Login.vue')
},
]
// 1 导入 vue.js
import Vue from 'vue'
import './cube-ui'
import App from './App.vue'
// 2 导入 路由文件
import router from './router'
import store from './store'
import axios from 'axios'
import 'amfe-flexible'
import steaxios from './setaxios'
steaxios();
Vue.config.productionTip = false
Vue.prototype.$http=axios//挂载axios
new Vue({
router,
store,
// 6 将路由实例挂载到vue实例
render: h => h(App)
}).$mount('#app')
通过代码注释中步骤,就完成路由基本功能的实现啦!
重定向
在这个小项目中,我是直接使用重定向,让页面一开始在根路径的时候就跳转到登陆页面。
{
// 将path 重定向到 redirect
path: '/',
name: 'login',
redirect: '/login'
},
重定向还有两种方式
- 重定向的目标可以是一个命名的路由:
{ path: '/', redirect: { name: 'login' }}
- 重定向的目标可以是一个方法,动态返回重定向目标:
{ path: '/', redirect: to => {
// 方法接收 目标路由 作为参数
// return 重定向的 字符串路径/路径对象
}}
注:导航守卫并没有应用在跳转路由上,而仅仅应用在其目标上。
懒加载(延迟加载)
- 定义:懒加载也叫延迟加载,即在需要的时候进行加载,随用随载。
- 作用:路由懒加载可以帮我们在进入首屏时不用加载过度的资源,从而减少首屏加载速度。也就是按需加载。使用第三方组件库依赖过大,会给首屏加载带来很大的压力,一般解决方式是按需求引入组件。如果引用组件的组件,也是跳转到相应路由,再进行加载需要使用的组件,可以提高性能。
- 实现懒加载的三种方式:
一、Vue异步组件技术:
{
path: '/home',
name: 'Home',
component: resolve => reqire(['path路径'], resolve)
}
二、es6提案的import()
const Home = () => import('path路径')
//本项目使用的方式
{
path: '/login',
name: 'login',
component: () => import(/* webpackChunkName: "about" */ '../views/Login.vue')
},
三、webpack提供的require.ensure()
{
path: '/home',
name: 'Home',
component: r => require.ensure([],() => r(require('path路径')), 'demo')
}
总结来自:
作者:小梦哟
链接:https://juejin.im/post/5e4c0b856fb9a07ccb7e8eca
来源:掘金
可以手写懒加载源码吗?
这个问题我也想了一下,实现懒加载肯定是要直接操作DOM。作为前端小白的我能力有限,暂时无法完成,但是找到了一篇文章可以供大家参考。
- Vue实现懒加载的基本思路
懒加载的弊端
所有的东西都是一把双刃剑,有利也有弊,只能按需使用,切不可过度使用。
大项目中的路由懒加载不适用于开发环境(会导致保存代码时热更新代码时间很长20s左右)
解决办法
在 router/ 文件夹中加入2个文件夹:
_import_development.js
module.exports = file => require('@/' + file + '.vue').default
_import_production.js
module.exports = file => resolve => require(['@/' + file + '.vue'], resolve)
index.js
const IMPORT = require('./_import_' + process.env.NODE_ENV + '.js');
组件引入时写入:
component: IMPORT('pages/mainPage') // 组件
嵌套子路由
在我的小项目中也使用了嵌套路由。嵌套路由顾名思义,路由中又包含子路由。例如:
/botnav/index /botnav/list
+------------------+ +-----------------+
| botnav | | botnav |
| +--------------+ | | +-------------+ |
| | index | | +------------> | | list | |
| | | | | | | |
| +--------------+ | | +-------------+ |
+------------------+ +-----------------+
想要在botnav页面中,切换index,list等多个页面时,嵌套路由就派上用场啦,它的书写规则如下:
注:childern子路由path一定不要加上‘\’,写代码时,写路由路径写习惯了,很容易犯这个小错误
{
path: '/botnav',
name: 'botnav',
component: () => import('../views/Botnav.vue'),
children:[
{
path: 'index',
name: 'index',
component: () => import('../views/index.vue')
},
{
path: 'list',
name: 'list',
component: () => import('../views/List.vue')
},
{
path: 'search',
name: 'search',
component: () => import('../views/Search.vue')
},
{
path: 'cart',
name: 'cart',
component: () => import('../views/Cart.vue')
},
{
path: 'mine',
name: 'mine',
component: () => import('../views/Mine.vue')
},
]
}
实现效果:
这几个botnav就可以在同一个页面切换啦。
过渡动效
在写项目时,为了增加用户体验感,加上路由切换时的过渡动效是必不可少的,下面先看一下过度动效的效果展示:
以上代码建立了一个botnav,用
本项目中用silde-right替换了v-。
路由还有其他很多功能,我就不一一介绍啦,大家有兴趣可以去看看官方文档。下面我们来解答最后一个疑问,?可以写出路由跳转的源码吗?
可以写出路由跳转的源码吗?
想要知道路由的源码怎么写?一定要知道路由是怎么实现的。我浅显的理解是,对于路由的hush模式,我们切换一个页面,就是对一个视图的展示。需要对这个视图进行展示,一定想要获取这个页面的huas值,然后去对这个视图进行注册,然后进行展示。这样利用路由切换页面就成功啦。我不知道我的理解是否正确,希望大佬指出。下面我对我的思路进行源码的书写,先放上效果图。
我们先写三个链接:
然后我们定义一个hashRouter方法,并实现进入首页时,返回空。
class HashRouter {
//初始化时执行
registerIndex(cb = () => {}) {
this.routers.index = cb;
}
}
接下来我们进行获取hash和对页面视图进行注册:
class HashRouter {
constructor() {
this.routers = {}; //配置, 是设计关键点 routes
//存储路由配置的 hash key val Component
window.addEventListener('hashchange', () => {
let hash = window.location.hash.slice(1),//获取页面hash
handler;
if(!hash) {
handler = this.routers.index;
} else {
handler = this.routers[hash];
}
handler.call(this);//将hash抛出去
})
}
// hahschange 后执行哪个函数
// vue 组件 函数式组件 callback
register(hash, callback){
this.routers[hash] = callback;//进行视图注册
}
//初始化时执行
registerIndex(cb = () => {}) {
this.routers.index = cb;
}
}
最后我们将注册后的视图,插入到id="container",让页面显示
let router = new HashRouter(); //路由对象, 类型为hash
let container =
document.getElementById('container'); // 根组件
router.registerIndex(() => container.innerHTML = '首页')
router.register('/page1', function ()
{
console.log(this.routers);
container.innerHTML = '/page1';
}) // 路由 对应执行事 //.vue template部分
router.register('/page2', () => container.innerHTML = '/page2');
router.register('/page3', () => container.innerHTML = '/page3');
路由简单实现就完成啦,如有错误还望大佬指出。
写在后面
引用小金鱼的一句话,当然纸上学来终觉浅,绝知此事要躬行。学完理论就需要去实践,大家看完之后一定要自己去操作一下,不然似懂非懂,第二天就忘啦。在此作者再次附上GitHub的地址vue-jingdong (不要吝惜你的小星星哦)。这是一个系列文章,未完待续,期待与你一起学习。如果对你有帮助的话,不妨送上你的star,送人玫瑰,手留余香,谢谢!