vue-router 运行机制 及 底层原理
1.测试页面
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
.router-link-active{color: red;}
</style>
</head>
<body>
<!--
路由:异步加载
-->
<!--VueJs核心库-->
<script src="vue.js"></script>
<!--Router-->
<script src="vue-router.js"></script> <div id="app">
<h1>Hello App</h1>
<!--router-link被渲染成a标签,为什么直接用a标签而用router-link?-->
<router-link to="/index">Go to Index</router-link>
<router-link to="/subpage">Go to SubPage</router-link>
<!--渲染位置-->
<router-view></router-view>
</div> <script>
//VueJS的router-link,在没有使用之前,不会对任何Tag(标签)起到任何作用
//const和var一样都是声明变量的,ES6语法,const(声明常量)
//两套模板
const Foo = {template:'<div>Index</div>'}
const Bar = {template:'<div>SubPage</div>'} const routes = [ // 配置
//{路由名称:名字和路径,模板:模板的变量}
{path:'/index',component:Foo},
{path:'/subpage',component:Bar}
] const router = new VueRouter({ // 得到VueRouter的实例
routes
}); // new Vue({
// el:"#app", // 指定渲染位置
// data:{ // 数据
// message:'Hello App'
// }
// }); const app = new Vue({ //在一个地方传入的是一个对象,需要一对大括号
router
}).$mount('#app'); //指定位置
</script>
</body>
</html>
index2.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
.router-link-active{color: red;}
</style>
</head>
<body>
<div id="app">
<div>
<router-link to="/user/foo">/user/foo</router-link>
</div>
<div>
<router-link to="/user/bar">/user/bar</router-link>
</div>
<div>
<router-view></router-view>
</div>
</div> <!--VueJs核心库-->
<script src="vue.js"></script>
<!--Router-->
<script src="vue-router.js"></script> <!--配置动态路由-->
<script>
const User = {
template:`<div>User:{{$route.params.id}}</div>`
} const router = new VueRouter({
routes:[
{path:'/user/:id',component:User}
]
}); const app = new Vue({router}).$mount('#app');
</script>
</body>
</html>
2.函数封装
index3.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
.router-link-active{color: red;}
</style>
</head>
<body>
<a href="#/index?index=1">异步加载首页</a>
<a href="#/list?list=1">异步加载列表</a>
<a href="#/detail?detail=1">异步加载详情</a>
<a href="#/detail2?detail2=1">异步加载详情2</a> <div id="content">
默认
</div> <script src="myroute.js"></script>
<script>
// window.addEventListener('hashchange',function() { // 监听URL的改变
// console.log("Hello");
// }); spaRouters.init(); /*
1.开发都是异步的
*/ spaRouters.map("/index",function(transition){
spaRouters.asyncFun("index.js",transition)
}) spaRouters.map("/list",function(transition){
spaRouters.asyncFun("list.js",transition)
})
</script>
</body>
</html>
index.js
SPA_RESOLVE_INIT = function (transition) {
document.getElementById("content").innerHTML = "当前是渲染的页面";
}
list.js
SPA_RESOLVE_INIT = function (transition) {
document.getElementById("content").innerHTML = "当前是渲染的页面";
}
myroute.js
(function() { // 匿名函数,让代码处于局部
// 通过监听,改变页面的显示
function spaRouters() {
this.routers = {}; // 保存注册所有路由,也可以理解为缓存
}
var util = { // 声明公共类
getParamsUrl:function(){ // 获取路由的路径和参数
var hasDetail = location.hash.split("?");
var hasName = hasDetail[0].split("#")[1]; // 得到路由地址
var params = hasDetail[1]?hasDetail[1].split("&"):[]; // 得到参数
var query = {};
for (var i = 0; i < params.length; i++) {
var item = params[i].split("=");
query[item[0]] = item[1];
}
return {
path:hasName,
query:query
}; // 返回一个路由名称
}
}
// 一块业务
spaRouters.prototype = {
init:function(){
var self = this;
window.addEventListener('hashchange',function() { // 监听URL的改变
// 只是知道发生了改变,并不知道路径,需要路由处理
self.urlChange();
});
window.addEventListener('load',function() { // 监听URL的改变
// 只是知道发生了改变,并不知道路径,需要路由处理
self.urlChange();
});
},
refresh:function(currentHash){ // 加载
var self = this;
if (self.beforeFun) {
self.beforeFun({
to:{
path:currentHash.path,
query:currentHash.query
},
next:function(){
self.routers[currentHash.path].callback.call(self,currentHash);
}
})
}else{
self.routers[currentHash.path].callback.call(self,currentHash);
}
},
// URL 路由处理
urlChange:function(){
var currentHash = util.getParamsUrl();
if(this.routers[currentHash.path]){
this.refresh(currentHash);
}
},
// 仅仅作为注册路由
map:function(path,callback){
// 清除空格
path = path.replace(/\s*/g,""); // 过滤空格
if(callback && Object.prototype.toString.call(callback) === "[object Function]"){
this.routers[path] = {
callback:callback,
fn:null // 缓存异步文件状态
}
}else{
console.trace("注册"+path+"需要注册回调信息");
}
},
asyncFun:function(file,transition){
var self = this;
if(self.routers[transition.path].fn){
self.afterFun && self.afterFun(transition)
self.routers[transition.path].fn(transition)
}else{
console.log("开始异步下载js文件"+file);
var _body = document.getElementsByTagName("body")[0];
var scriptEle = document.createElement("script");
scriptEle.type = 'text/javascript';
scriptEle.src = file;
scriptEle.async = true;
SPA_RESOLVE_INIT = null;
scriptEle.onload = function(){ // 加载文件之后
console.log("下载"+file+"完成");
self.afterFun && self.afterFun(transition)
self.routers[transition.path].fn = SPA_RESOLVE_INIT;
self.routers[transition.path].fn(transition)
}
_body.appendChild(scriptEle);
}
}
}
window.spaRouters = new spaRouters(); // 注册到全局
})();
.
vue-router 运行机制 及 底层原理的更多相关文章
- php--->底层的运行机制与数据结构原理
PHP 底层的运行机制与数据结构原理 1. PHP的设计理念及特点 多进程模型:由于PHP是多进程模型,不同请求间互不干涉,这样保证了一个请求挂掉不会对全盘服务造成影响,当然,随着时代发展,PHP也早 ...
- Vue异步更新机制以及$nextTick原理
相信很多人会好奇Vue内部的更新机制,或者平时工作中遇到的一些奇怪的问题需要使用$nextTick来解决,今天我们就来聊一聊Vue中的异步更新机制以及$nextTick原理 Vue的异步更新 可能你还 ...
- Java并发(二)—— 并发编程的挑战 与 并发机制的底层原理
单核处理器也可以支持多线程,因为CPU是通过时间片分配算法来循环执行任务 多线程一定比单线程快么?不一定,因为线程创建和上下文切换都需要开销. 如何减少上下文切换 无锁并发编程 CAS算法 使用最少线 ...
- PHP的运行机制与原理(底层) [转]
说到php的运行机制还要先给大家介绍php的模块,PHP总共有三个模块:内核.Zend引擎.以及扩展层:PHP内核用来处理请求.文件流.错误处理等相关操作:Zend引擎(ZE)用以将源文件转换成机器语 ...
- PHP的运行机制与原理(底层)
原文:http://www.jb51.net/article/74907.htm 说到php的运行机制还要先给大家介绍php的模块,PHP总共有三个模块:内核.Zend引擎.以及扩展层:PHP内核用来 ...
- 微信小程序底层原理与运行机制类文章学习
参考文档 小程序底层实现原理及一些思考 为了安全和管控, 双线程执行 Web Worker执行用户的代码; UI线程执行大部分的功能. 微信小程序架构原理 只通过mvvm模板语法动态改变页面, 不支持 ...
- 【Spark 深入学习 04】再说Spark底层运行机制
本节内容 · spark底层执行机制 · 细说RDD构建过程 · Job Stage的划分算法 · Task最佳计算位置算法 一.spark底层执行机制 对于Spark底层的运行原理,找到了一副很好的 ...
- PHP5底层原理之垃圾回收机制
概念 垃圾回收机制 是一种内存动态分配的方案,它会自动释放程序不再使用的已分配的内存块. 垃圾回收机制 可以让程序员不必过分关心程序内存分配,从而将更多的精力投入到业务逻辑. 与之相关的一个概念,内存 ...
- Java 并发系列之二:java 并发机制的底层实现原理
1. 处理器实现原子操作 2. volatile /** 补充: 主要作用:内存可见性,是变量在多个线程中可见,修饰变量,解决一写多读的问题. 轻量级的synchronized,不会造成阻塞.性能比s ...
随机推荐
- [ CodeVS冲杯之路 ] P3027
不充钱,你怎么AC? 题目:http://codevs.cn/problem/3027/ 显然是DP题,先按线段的右端点升序排序 设 f[i] 为dp到第 i 个线段时最大的价值 目标状态为 max( ...
- /proc/sys/shm/drop_caches
author:skate time:2012/02/22 手工释放linux内存--/proc/sys/vm/drop_cache 转载一篇文章 linux的内存查看: [root@localhost ...
- Centos7下zabbix部署(五)定义报警媒介-微信
1.注册微信 注册过程参考地址:https://www.cnblogs.com/hanyifeng/p/5368102.html 主要需要以下一些信息 CorpID : wwxxxxxxxxx ...
- HDU 2063.过山车-Hungary(匈牙利算法)
过山车 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- (6)C#方法,作用域,方法重载
1.方法 返回类型 方法名(参数列表) 例如:int a(int b,int c) { 方法体 return b+c; } 函数如果有返回类型则最后要用return一个和返回类型一样的数据. 2.无返 ...
- HDU 5732 Subway(2016多校1J,树的重心 + 哈希)
题目链接 2016多校1 Problem J 题意 给定两棵相同的树,但是编号方案不同.求第一棵树上的每个点对应的第二棵树上的点.输出一种方案即可. 首先确定树的直径的中点.两棵树相等意味着两棵树 ...
- Python的Web编程[0] -> Web客户端[0] -> 统一资源定位符 URL
统一资源定位符 / URL 目录 URL 构成 URL 解析 URL 处理 1 URL构成 统一资源定位符(Uniform Resource Locator) 是对可以从互联网上得到的资源的位置和访问 ...
- 干净卸载mysql
一.在控制面板中卸载mysql软件 二.卸载过后删除C:\Program Files (x86)\MySQL该目录下剩余了所有文件,把mysql文件夹也删了 三.windows+R运行“regedit ...
- 洛谷——P1093 奖学金
P1093 奖学金 题目描述 某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前5名学生发奖学金.期末,每个学生都有3门课的成绩:语文.数学.英语.先按总分从高到低排序,如果两个同学总分相 ...
- [POI2007]Tourist Attractions
题目大意: 给你一个$n(n\leq 2\times 10^4)$个点,$m(m\leq 2\times 10^5)$条边的带边权的连通图.其中有$k(k\leq 20)$个关键点.关键点之间有$g$ ...