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的更多相关文章

  1. vue原理相关

    vue原理三大模块:响应式.vdom和diff.模板编译 vue原理要点: 1.组件化 组件化的历史:在vue之前已经有组件化的概念了,想asp.jsp.php等就有组件化的概念,nodejs也有组件 ...

  2. 剖析Vue原理&实现双向绑定MVVM

    转自:http://www.w3cmark.com/2016/496.html 本文能帮你做什么? 1.了解vue的双向数据绑定原理以及核心代码模块 2.缓解好奇心的同时了解如何实现双向绑定 为了便于 ...

  3. vue原理简介

    写vue也有一段时间了,对vue的底层原理虽然有一些了解,这里总结一下. vue.js中有两个核心功能:响应式数据绑定,组件系统.主流的mvc框架都实现了单向数据绑定,而双向绑定无非是在单向绑定基础上 ...

  4. vue原理探索--响应式系统

    Vue.js 是一款 MVVM 框架,数据模型仅仅是普通的 JavaScript 对象,但是对这些对象进行操作时,却能影响对应视图,它的核心实现就是「响应式系统」. 首先看一下 Object.defi ...

  5. 剖析Vue原理&实现双向绑定MVVM-2

    vue.js 最核心的功能有两个,一是响应式的数据绑定系统,二是组件系统.本文仅探究双向绑定是怎样实现的.先讲涉及的知识点,再用简化得不能再简化的代码实现一个简单的 hello world 示例. 一 ...

  6. 剖析Vue原理&实现双向绑定MVVM-1

    本文能帮你做什么?1.了解vue的双向数据绑定原理以及核心代码模块2.缓解好奇心的同时了解如何实现双向绑定为了便于说明原理与实现,本文相关代码主要摘自vue源码, 并进行了简化改造,相对较简陋,并未考 ...

  7. vue原理实现

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. [转] Vue原理解析——自己写个Vue

    一.Vue对比其他框架原理 Vue相对于React,Angular更加综合一点.AngularJS则使用了“脏值检测”. React则采用避免直接操作DOM的虚拟dom树.而Vue则采用的是 Obje ...

  9. Vue原理解析——自己写个Vue

    Vue由于其高效的性能和灵活入门简单.轻量的特点下变得火热.在当今前端越来越普遍的使用,今天来剖析一下Vue的深入响应式原理. tips:转自我的博客唐益达博客,此为原创.转载请注明出处,原文链接 一 ...

随机推荐

  1. git学习01- 下载安装&初始化库&提交

    1.windows下安装git,git官网下载安装包安装 2.本地创建一个目录,在目录下创建1个文本 readme.txt 3.cmd进入到该目录,执行git init,初始化git仓库 4.添加文件 ...

  2. 【简】题解 AWSL090429 【数塔问题】

    因为每次只ban一个点 而且不是永久性的 预处理出每个点从上往下和从下往上的最大值 每次询问直接暴力 被ban掉点那行去掉那点的最大值 也可以直接预处理出每行的最大值和次大值 还有种做法貌似可以过 预 ...

  3. linux的/etc/profile、~/.profile、~/.bashrc、~./bash_profile这几个配置文件

    在添加环境变量的时候,我们会去修改配置文件 如果留意过,网上博文,有些在/etc/profile文件中配置的,有些是在~./bash_profile文件中配置的,等等 那么,/etc/profile. ...

  4. IOC的理解(转载)

    转载自:https://www.zhihu.com/question/23277575/answer/169698662 要了解控制反转( Inversion of Control ), 我觉得有必要 ...

  5. 机器学习KNN算法

    KNN(最邻近规则分类K-Nearest-Neighibor)KNN算法 1. 综述      1.1 Cover和Hart在1968年提出了最初的邻近算法      1.2 分类(classific ...

  6. C++:普通变量C++命名规则

    C++提倡使用拥有一定意义的变量名,使程序代码更有阅读性,命名是必须使用的几种简单的C++命名规则: 命名时只能使用:字母字符.数字和下划线(_); 第一个字符不能是数字: 区分大小写(C++对大小写 ...

  7. UML(聚合、组合、依赖、继承、接口、类)

  8. .net core引用错误的Entity Framework而导致不能正常迁移数据的解决办法

    本人刚学.net core,因此在学习过程中会遇上许许多多的坑.每一位初学者最大的问题在于资料的查看不仔细或是没有正确理解里面的内容,导致在后面自己在不知道错误的情况下做了一个小动作.对于完全没有理解 ...

  9. HDU 1228(字符串处理)

    题意是将所给算式求出结果. 用的方法非常麻烦,开始没考虑到零也需要处理,以为遇上零直接跳过即可,知道发现零可以占位,比如 one zero 值为 10 而不是 1…… 代码如下: #include & ...

  10. Java位运算原理及使用讲解

    前言日常开发中位运算不是很常用,但是巧妙的使用位运算可以大量减少运行开销,优化算法.举个例子,翻转操作比较常见,比如初始值为1,操作一次变为0,再操作一次变为1.可能的做法是使用三木运算符,判断原始值 ...