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. python第七天

    复习: 1.深浅拷贝 值拷贝:直接赋值 = 号, 列表中的任何值发生改变,第二个中的值都会随之改变浅拷贝:通过copy()方法 ls2 = ls.copy(),第一个中存放的值的地址没有改变, 但内部 ...

  2. 处理 Vue 单页面应用 SEO

    由于在vue单页应用中title只设定在入口文件index.html,如果切换路由,title怎么更换? 在路由router中设置meta: { path:'/chooseBrand', compon ...

  3. 第一个thinkphp项目遇到的知识

    本文是于项目完成后所写,基本是想到 哪写到哪,所以顺序会很乱. 1.在后台处理ueditor这种文本编辑器的时候,会遇到取值问题,如果你想要取纯文本内容:getContentTxt(),没有段落格式: ...

  4. 关于std::cin阻塞事件循环以及控制台命令输入功能的方案;

    如果将std::cin建立在主线程,将阻塞主线程的所有事件循环,因而要保证事件循环不受影响,需要将std::cin放到 子线程中.同时,如果要实现能够强制终止std::cin阻塞, 可以通过强制终止线 ...

  5. 野路子码农系列(1) 创建Web API

    新工作正式开始了2天,由于客户暂时还没交接数据过来,暂时无事可做.恰逢政佬给某超市做的商品图像识别的项目客户催收了,老板要求赶紧搞个API,于是我就想我来试试吧. 说起API,我其实是一窍不通的,我对 ...

  6. Ansible-基础

    Ansible架构 Inventory   主机清单,可以对主机分组 ansible-hoc   ansible的命令,适用临时场景 ansible-playbook   ansible是一个场景的集 ...

  7. webpack-dev-server live reloading 技术实现

    webpack-dev-server  live reloading https://github.com/webpack/webpack-dev-server Use webpack with a ...

  8. springBoot和Mybatis输出sql日志

    利用slf4j来输出日志. 首先需要版本兼容的slf4j-log4j12.log4j.slf4j-api.slf4j-nop.slf4j-simple这5个包. 可以去maven知识库中找到这5个包的 ...

  9. P2P互联网金融企业的四大转型方向

    1.按照国标做成百分百的信息中介平台.这个定位太低,无利可图,如果政策导向真按着这个路径走,未来可能只剩下不到50家平台; 2.转型成为带“民营银行”属性的平台.这还得国家网开一面,学习英国模式,允许 ...

  10. Redis 简介与命令操作

    redis 是 key-value 的数据,所以每个数据都是一个键值对,键的类型是字符串: 值的类型分为五种:string.hash.list.set(集合).zset(有序集合). 数据操作的全部命 ...