vue原理20181211
1. 打开浏览器从输入网址到网页呈现出来,经历了什么?
打开浏览器从输入网址到网页呈现出来,经历了什么?
1.1 DNS解析域名
1.2 TCP连接:TCP三次握手
1.3 发送HTTP请求
1.4 服务器处理请求并返回HTTP报文
1.5 浏览器解析渲染页面
1.6 断开连接: TCP四次挥手 1.网址 URL(Uniform Resource Locator)
格式:scheme://host.domain:port/path/filename
scheme: http/https/ftp
host 主机 http 的默认主机是 www
domain 域名 baidu.com
port 端口 http 的默认端口号是 80 2.IP 地址,32位的二进制数 3.DNS解析:将域名解析成IP地址 baidu.com 220.114.33.55
浏览器并不能直接通过域名找到对应的服务器,而是要通过 IP 地址。
查找域名和IP的对应记录:从浏览器缓存、操作系统缓存、路由器缓存、ISP的DNS服务器、根服务器依次查找记录
根服务器进行递归查询:从查.cn 再查 .com.cn 再查 baidu.com.cn 再查 www.baidu.com.cn 4.TCP三次握手:
第一次握手:浏览器发送数据包到服务器端口,告诉浏览器要发送请求了
第二次握手:服务器发送响应包以传达确认信息,告诉浏览器可以发送了
第三次握手:浏览器再发数据包告诉服务器,马上要发了,准备接受 5.http请求
TCP 三次握手结束后,开始发送 HTTP 请求报文。
请求报文由请求行(request line)、请求头(header)、请求体四个部分组成 请求行包含请求方法(get post)、URL、协议版本(http版本号)
example: POST /chapter17/user.html HTTP/1.1
请求头是键值对
请求体 example: name=kang 6. http响应报文
响应报文由响应行(request line)、响应头部(header)、响应主体三个部分组成
响应行包含:协议版本,状态码,状态码描述
状态码 200 404 500 7. 浏览器渲染机制
根据 HTML 解析出 DOM 树
根据 CSS 解析生成 CSS 规则树
结合 DOM 树和 CSS 规则树,生成渲染树
根据渲染树计算每一个节点的信息(布局)
根据计算好的信息绘制页面(paint) 解析DOM树时,遇到script标签,会等脚本先执行
解析CSS树时,js执行会暂停,
精简 CSS 并可以加快 CSS 规则树的构建,从而加快页面相应速度
重绘:绘制页面时,某元素颜色等(不影响其他元素布局的属性)发生变化
回流:绘制页面时,某元素尺寸发生变化,要重新计算渲染树,重新渲染 8. 断开tcp连接,发起tcp四次挥手
第一次挥手:浏览器发送给服务器,表示请求报文已发完,你可以关闭了
第二次挥手:服务器发给浏览器,请求报文接收完,准备关闭
第三次挥手:服务器发给浏览器,响应报文发送完,你准备关闭
第四次挥手:浏览器发给服务器,响应报文完了,准备关闭 HTTP 请求阶段,HTTP 请求分为三个部分:TCP 三次握手、http 请求响应信息、关闭 TCP 连接。 浏览器向dns服务器发送域名,DNS服务器查询并返回IP地址,浏览器再发送到对应服务器请求数据 参考链接:https://mp.weixin.qq.com/s?__biz=MzAxODE2MjM1MA==&mid=2651555392&idx=1&sn=9042c990f82fe5d03f03e6af7536b4c3&chksm=80255181b752d897524a6f1ee332f245761c89a5e01d0cbf0499e3a74a21f3865f8cfff823cf&mpshare=1&scene=1&srcid=1126MqCAj6jUV3jqGvxxDNAF#rd
【以下为vue实现原理相关知识点】
2. document.createDocumentFragment() fragment 文档片段,存于内存中,不在DOM树,性能好 例子来自 mdn
/**
* document.createDocumentFragment()
* DocumentFragments 是DOM节点
* 创建文档片段,将元素附加到文档片段,然后将文档片段附加到DOM树。
* 因为文档片段存在于内存中,并不在DOM树中,所以将子元素插入到文档片段时不会引起页面回流(对元素位置和几何上的计算)。因此,使用文档片段通常会带来更好的性能。
*/
function fragment () { var element = document.getElementById('ul') // assuming ul exists
var fragment = document.createDocumentFragment() // 存于内存,不在DOM树,性能好
var browsers = ['Firefox', 'Chrome', 'Opera',
'Safari', 'Internet Explorer'] browsers.forEach(function (browser) {
var li = document.createElement('li')
li.textContent = browser
fragment.appendChild(li) // 先追加到 fragment
}) element.appendChild(fragment) // 再追加到dom节点
} fragment()
3.nodeType 1是元素 3是文本
function nodeType () {
var p = document.createElement("p");
p.textContent = "很久很久以前..."; console.log(Node.ELEMENT_NODE === 1) // p
console.log(Node.TEXT_NODE === 3) // 很久很久以前... console.log(p.nodeType === Node.ELEMENT_NODE) // true
console.log(p.firstChild) // 很久很久以前...
console.log(p.firstChild.nodeType === Node.TEXT_NODE) // true
}
4.white循环 对比for循环
function whiteTest() {
let arr = [1, 2, 3, 4, 5]
let brr = []
i = 0
while (i < 3) {
brr.push(arr[i])
i++
}
console.log(brr) // [0,1,2] for(var i =0;i<3;i++){ brr.push(arr[i])}
}
5.正则 * 0~多 + 1~多 ? 0~1 .匹配所有字符
/**
* 正则 * 0~多 + 1~多 ? 0~1 .匹配所有字符
* @param text
* @returns {boolean}
*/
function isReg (text) {
let reg = /\{\{(.*)\}\}/ // * 0~多 + 1~多 ? 0~1 .匹配所有字符
return reg.test(text)
} console.log(isReg('{{}}')) // true
console.log(isReg('{{.gfg}}')) // true
console.log(isReg('{{.g}}')) // true
6. node节点操作 firstChild 节点不要出现换行等
<p id="para-01">
<span>First span</span>
</p> <script type="text/javascript">
/*
* 在<p>标签和<span>标签之前,有一个换行符和多个空格充当了一个文本节点,导致 结果为 #text
* 操作node节点不要出现空格
* */
var p01 = document.getElementById('para-01');
console.log((p01.firstChild)) // #text 大对象
console.log((p01.firstChild.nodeName)) // #text
</script>
<p id="para-012"><span>First span</span></p> <script type="text/javascript">
var p012 = document.getElementById('para-012');
console.log((p012.firstChild)) // <span>First span</span>
console.log((p012.firstChild.nodeName)) // SPAN
console.log((p012.firstChild.firstChild.nodeValue)) // First span
console.log((p012.firstChild.innerHTML)) // First span </script>
7. li 标签转换成数组操作 也可以用 for 来解决 [].slice.call($Li).forEach(val=>{})
/*
* 原数组的浅拷贝 slice()
* arr.slice();
// [0, end] arr.slice(begin);
// [begin, end] arr.slice(begin, end);
// [begin, end) [].slice.call($li) // li标签复制一份,转换为数组调用 forEach
* */ let $li = document.getElementsByTagName('li')
console.log($li)
for(var i=0;i<$li.length;i++){
console.log($li[i].firstChild.nodeValue)
console.log($li[i].innerHTML.replace(/^abc/, ''))
}
console.log('-------');
console.log('dd',[].slice.call($li));
[].slice.call($li).forEach(val=>{
val.innerHTML=val.innerHTML.replace(/^abc/,'')
})
8. 对象的 for循环 Object.keys(obj).forEach(key=>{}) 同时拿到 obj key val
let obj = {
name:'kang',
age:12,
date:{
y:2018,
m:12,
d:13
}
}
Object.keys(obj).forEach(key=>{
console.log(obj)
console.log(key)
console.log(obj[key])
})
9.Object.defineProperty() 对象监听
let obj = {name: 'kang', age: 12, date: {y: 12}} observe(obj)
obj.name = 'jia'
obj.age = 20
obj.date.y = 11
for (var i in obj) { // enumerable 为false时,无法使用 for...in 和 object.keys()
// console.log('df',i)
} var o = { // 用这个方式时,enumerable为 true 可用 for...in
d: 1
} /**
* 监听对象
* @param obj
*/
function observe (obj) {
if (!obj || typeof obj !== 'object') return // 遍历所有对象
Object.keys(obj).forEach(key => {
// obj 原对象
// key : name age date
// obj[key]: kang 12 {y:12}
// obj[key] 有可能是个对象,所以要再递归
listen(obj, key, obj[key])
})
} /**
* Object.defineProperty 监听属性变动
* @param data
* @param key
* @param val
*/
function listen (data, key, val) {
observe(val) // 递归 先把递归注释掉容易理解点
// Obeject.defineProperty() 来监听属性变动
Object.defineProperty(data, key, {
enumerable: true, // 可枚举 默认为false enumerable定义了对象的属性是否可以在 for...in 循环和 Object.keys() 中被枚举。
get: function () {
return val
},
set: function (newVal) {
if (val === newVal) return
console.log('监听到新值了', val, '->', newVal)
val = newVal
}
})
}
10. node节点操作 node.firstChild childNodes textContent nodeType attributes
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<input type="text" v-model="someStr">
<p>{{getHelloWord}}</p>
<p v-html="htmlStr"></p>
<button v-on:click="clickBtn">change model</button>
</div> <script>
let $el = document.querySelector('#app')
let $fragment = node2Fragment($el) // 转成 文档碎片,在DOM上不会显示出来
$el.appendChild($fragment) // console.log($el.textContent) // 返回该元素下所有文本节点 {{getHelloWord}} change model function node2Fragment ($el) {
let fragment = document.createDocumentFragment()
while ($el.firstChild) {
// console.log($el.firstChild) // #text <input type=...> #text <p>{{... #text <p v...> #text <button...> #text
// 两个标签之间的空格换行解析成 #text 文本节点
fragment.appendChild($el.firstChild)
}
// 方式二
/* for(;$el.firstChild;){ // for 三个条件可以省略第一个,第三个(可能写在for前面、for里面),只要能够执行
fragment.appendChild($el.firstChild)
}*/ // 方式三 最好理解
/* ;[].slice.call($el.childNodes).forEach(node=>{
fragment.appendChild(node)
})*/
return fragment
} /*
* https://developer.mozilla.org/en-US/docs/Web/API/Node
*
* node.firstChild 返回第一个child node or null
* node.childNodes 返回nodeList 包含所有 children 如果children变了,nodeList会自动更新
* node.textContent 返回或者设置元素及其子元素的所有文本节点 空格部分为 ''
* node.nodeType 1 是元素ELEMENT_NODE <div>...</div> 3 是文本TEXT_NODE #text
* */ // console.log($el.firstChild) // #text 只拿到第一个空格部分
// console.log($el.childNodes); // NodeList[text,input,text,p,text,p,text,button,text] 空格解析为text
;[].slice.call($el.childNodes).forEach(node => {
// console.log(node) // #text <input type='text' v-model='somestr'> #text
// console.log(node.textContent) // '' {{getHelloWord}} change model ''
// console.log(node.nodeType) // 3 1 3
// console.log(node.attributes) // undefined NameNodeMap{} undefined if (node.nodeType === 1) { // 处理元素节点 <div class='a'>...</div>
elementNode(node)
} else if (node.nodeType === 3) { // 处理 {{xx}}
let reg = /\{\{.*\}\}/
let text = node.textContent
console.log(text)
if (reg.test(text)) { console.log(node)
}
}
}) /*
* DOM1级主要定义的还是HTML的地层结构,DOM2和DOM3级则在这个结构的基础上引入了更多的交互能力
*
* node.attributes DOM4 删除该属性,目前还是DOM2 DOM3 元素节点属性
*
*
*
*
* */
function elementNode (node) {
var nodeAttr = node.attributes
;[].slice.call(nodeAttr).forEach(attr => {
var attrName = attr.name
// console.log(attr) // type='text' v-model='someStr' 等
// console.log(attr.name) // type v-model 等
// console.log(attr.value) // text someStr
})
}
</script>
</body>
</html>
【暂停】
2-10为vue双向绑定原理知识点
教程 https://segmentfault.com/a/1190000006599500#articleHeader3
源码: https://github.com/gyz418/mvvm
vue原理20181211的更多相关文章
- vue原理相关
vue原理三大模块:响应式.vdom和diff.模板编译 vue原理要点: 1.组件化 组件化的历史:在vue之前已经有组件化的概念了,想asp.jsp.php等就有组件化的概念,nodejs也有组件 ...
- 剖析Vue原理&实现双向绑定MVVM
转自:http://www.w3cmark.com/2016/496.html 本文能帮你做什么? 1.了解vue的双向数据绑定原理以及核心代码模块 2.缓解好奇心的同时了解如何实现双向绑定 为了便于 ...
- vue原理简介
写vue也有一段时间了,对vue的底层原理虽然有一些了解,这里总结一下. vue.js中有两个核心功能:响应式数据绑定,组件系统.主流的mvc框架都实现了单向数据绑定,而双向绑定无非是在单向绑定基础上 ...
- vue原理探索--响应式系统
Vue.js 是一款 MVVM 框架,数据模型仅仅是普通的 JavaScript 对象,但是对这些对象进行操作时,却能影响对应视图,它的核心实现就是「响应式系统」. 首先看一下 Object.defi ...
- 剖析Vue原理&实现双向绑定MVVM-2
vue.js 最核心的功能有两个,一是响应式的数据绑定系统,二是组件系统.本文仅探究双向绑定是怎样实现的.先讲涉及的知识点,再用简化得不能再简化的代码实现一个简单的 hello world 示例. 一 ...
- 剖析Vue原理&实现双向绑定MVVM-1
本文能帮你做什么?1.了解vue的双向数据绑定原理以及核心代码模块2.缓解好奇心的同时了解如何实现双向绑定为了便于说明原理与实现,本文相关代码主要摘自vue源码, 并进行了简化改造,相对较简陋,并未考 ...
- vue原理实现
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- [转] Vue原理解析——自己写个Vue
一.Vue对比其他框架原理 Vue相对于React,Angular更加综合一点.AngularJS则使用了“脏值检测”. React则采用避免直接操作DOM的虚拟dom树.而Vue则采用的是 Obje ...
- Vue原理解析——自己写个Vue
Vue由于其高效的性能和灵活入门简单.轻量的特点下变得火热.在当今前端越来越普遍的使用,今天来剖析一下Vue的深入响应式原理. tips:转自我的博客唐益达博客,此为原创.转载请注明出处,原文链接 一 ...
随机推荐
- git学习01- 下载安装&初始化库&提交
1.windows下安装git,git官网下载安装包安装 2.本地创建一个目录,在目录下创建1个文本 readme.txt 3.cmd进入到该目录,执行git init,初始化git仓库 4.添加文件 ...
- TJOI2018Party
题目描述 小豆参加了\(NOI\)的游园会,会场上每完成一个项目就会获得一个奖章,奖章 只会是\(N\), \(O\), \(I\)的字样.在会场上他收集到了\(K\)个奖章组成的串. 兑奖规则是奖章 ...
- 小计:Shopee批量删除修复~附脚本
需求 昨天浪的时候,无意之间看到文职人员在一个个删除违禁商品,大概23个店铺,每个店铺500多个商品,页面是用Ajax异步加载的,每删一个就需要等几秒,粗略估计一下用时:9h左右 然后了解了下是什么情 ...
- 《Exception团队》第一次作业:团队亮相
一.项目基本介绍 项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 作业链接地址 团队名称 Exception 作业学习目标 深入了解软件思想,强化编程技术 二.正文 1. ...
- blaze介绍
sklearn实战-乳腺癌细胞数据挖掘 https://study.163.com/course/introduction.htm?courseId=1005269003&utm_campai ...
- Hadoop大数据通用处理平台
1.简介 Hadoop是一款开源的大数据通用处理平台,其提供了分布式存储和分布式离线计算,适合大规模数据.流式数据(写一次,读多次),不适合低延时的访问.大量的小文件以及频繁修改的文件. *Hadoo ...
- [C#] .NET4.0中使用4.5中的 async/await 功能实现异步
在.NET Framework 4.5中添加了新的异步操作库,但是在.NET Framework 4.0中却无法使用.这时不免面临着抉择,到底是升级整个解决方案还是不使用呢? 如果你的软件还没发布出去 ...
- 前端面试题整理—Webpack篇
1.什么是webpack,与grunt和gulp有啥不同 webpack是一个模块打包工具,在webpack里面一切皆模块 通过loader转换文件,通过plugin注入钩子,最后输出有多个模块组合成 ...
- 模拟赛20181015 Uva1078 bfs+四维dp
题意:一张网格图,多组数据,输入n,m,sx,sy,tx,ty大小,起终点 接下来共有2n-1行,奇数行有m-1个数,表示横向的边权,偶数行有m个数,表示纵向的边权 样例输入: 4 4 1 1 ...
- Mybatis多表链接查询重复字段问题
A表和B表一对多的关系 A表 B表 A表和C表也是一对多关系 C表 我现在向查询出A表的所有字段和B表的name字段,C表的name字段 这是我错误的sql语句,可以看出我没有查B表和C表的id字段, ...