- animation 与 keyframes结合
- 6个属性 name、duration、timing-function(动画速度曲线linear、ease、cubic-bezier)、delay、iteration-count(播放次数)、direction(是否应该轮流反向播放动画,normal,alternate)
- 简单实例
animation:mymove 5s infinite;
- transition 主要是起过渡效果
- 4个属性 property(none|all|property)、duration、timing-function、delay
- 当属性发生变化的时候,过渡效果才会起作用
- 简单实例
transition: all 2s;
- js强行实现
- 不推荐,直接用js定时器修改style样式形成动画,会出现卡帧现象。
- canvas动画
- canvas能够动起来也是js控制的,因此我认为属于js动画当中,主要操作就是绘制-清空-绘制,常用方法用Interval定时器。但是也可能出现卡帧的现象,建议动画渲染慢的时候使用,复杂的时候使用。
- requestAnimationFrame
- requestAnimationFrame是另一种Web API,原理与setTimeout和setInterval类似,都是通过javascript持续循环的方法调用来触发动画动作。但是requestAnimationFrame是浏览器针对动画专门优化形成的APi,在性能上比另两者要好。通常,我们将执行动画的每一步传到requestAnimationFrame中,在每次执行完后进行异步回调来连续触发动画效果。
- requestAnimationFrame的特点可以让他用在canvas动画上,也可以做到避免卡帧
- 简单实例:
var start = null; var element = document.getElementById('SomeElementYouWantToAnimate'); element.style.position = 'absolute'; function step(timestamp) { if (!start) start = timestamp; var progress = timestamp - start; element.style.left = Math.min(progress / 10, 200) + 'px'; if (progress < 2000) { window.requestAnimationFrame(step); } } window.requestAnimationFrame(step);
- Tip 16ms
我们设置的setInterval时间间隔是16ms。一般认为人眼能辨识的流畅动画为每秒60帧,这里16ms比(1000ms/60)帧略小一些,但是一般可仍为该动画是流畅的。
在很多移动端动画性能优化时,一般使用16ms来进行节流处理连续触发的浏览器事件。例如对touchmove、scroll事件进行节流等。通过这种方式减少持续事件的触发频率,可以大大提升动画的流畅性。
- 具体实现:给image设定attr-img属性,值设置为图片的url,当滚轮滚动到图片位置,js操作将attr-img设置设置到image的url。
- 为了节约 window.onscroll的次数 ,提高性能, 设计了函数节流和函数防抖两种模式
- 多次触发事件后,事件处理函数只执行一次,并且是在触发操作结束时执行。
- 原理:对处理函数进行延时操作,若设定的延时到来之前,再次触发事件,则清除上一次的延时操作定时器,重新定时。
- 简单实例:
强制方法 let timer; window.onscroll = function () { if(timer){ clearTimeout(timer) } timer = setTimeout(function () { //滚动条位置 let scrollTop = document.body.scrollTop || document.documentElement.scrollTop; console.log('滚动条位置:' + scrollTop); timer = undefined; },200) } //轮子 function debouncing(fn, delay) { var timer = null; return function () { var context = this; var args = arguments; clearTimeout(timer) timer = setTimeout(function () { fn.apply(context,args) },delay) } }
- 触发函数事件后,短时间间隔内无法连续调用,只有上一次函数执行后,过了规定的时间间隔,才能进行下一次的函数调用。
- 原理:对处理函数进行延时操作,若设定的延时到来之前,再次触发事件,则清除上一次的延时操作定时器,重新定时。
- 简单实例:
let startTime = Date.now(); //开始时间 let time = 500; //间隔时间 let timer; window.onscroll = function throttle(){ let currentTime = Date.now(); if(currentTime - startTime >= time){ let scrollTop = document.body.scrollTop || document.documentElement.scrollTop; console.log('滚动条位置:' + scrollTop); startTime = currentTime; }else{ clearTimeout(timer); timer = setTimeout(function () { throttle() }, 50); } } //轮子 function throttle(delay, fn) { var last = 0; return function () { var curr = +new Date() if(curr-last>delay){ fn.apply(this,arguments) last = curr } } }
- flex-direction
- 定主轴的方向,项目的排列方向
.box { flex-direction: row | row-reverse | column | column-reverse; }
- row(默认值):主轴为水平方向,起点在左端。
- row-reverse:主轴为水平方向,起点在右端。
- column:主轴为垂直方向,起点在上沿。
- column-reverse:主轴为垂直方向,起点在下沿。
- flex-wrap
- 是否换行
.box{ flex-wrap: nowrap | wrap | wrap-reverse; }
- nowrap(默认):不换行。
- wrap:换行,第一行在上方。
- wrap-reverse:换行,第一行在下方。
- flex-flow
- flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
.box { flex-flow: <flex-direction> || <flex-wrap>; }
- justify-content
- 项目在主轴上的对齐方式
.box { justify-content: flex-start | flex-end | center | space-between | space-around; }
- flex-start(默认值):左对齐
- flex-end:右对齐
- center: 居中
- space-between:两端对齐,项目之间的间隔都相等。
- space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍
- align-items
- 定义项目在交叉轴上如何对齐方式
.box { align-items: flex-start | flex-end | center | baseline | stretch; }
- flex-start:交叉轴的起点对齐。
- flex-end:交叉轴的终点对齐。
- center:交叉轴的中点对齐。
- baseline: 项目的第一行文字的基线对齐。
- stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
- align-content
- 定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
.box { align-content: flex-start | flex-end | center | space-between | space-around | stretch; }
- flex-start:与交叉轴的起点对齐。
- flex-end:与交叉轴的终点对齐。
- center:与交叉轴的中点对齐。
- space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
- space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
- stretch(默认值):轴线占满整个交叉轴。
- Tip flex布局有几根轴?
- 水平的主轴(main axis)
- 竖直的交叉轴
- order
- 定义项目的排列顺序。数值越小,排列越靠前,默认为0
.item { order: <integer>; }
- flex-grow
- 定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大
.item { flex-grow: <number>; /* default 0 */ }
- 如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。
- flex-shrink 定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小
.item { flex-shrink: <number>; /* default 1 */ }
-
如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。
-
负值对该属性无效。
-
- flex-basis
- 属性定义了在分配多余空间之前,项目占据的主轴空间(main size).浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。
.item { flex-basis: <length> | auto; /* default auto */ }
- 它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间。
- flex
- flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。
.item { flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ] }
- auto 等于 (1 1 auto)
- none 等于 (0 0 auto)
- 1 等于 (1 1 0%)
- align-self
- 允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
.item { align-self: auto | flex-start | flex-end | center | baseline | stretch; }
- 该属性可能取6个值,除了auto,其他都与align-items属性完全一致。
-
标签选择器(如:body,div,p,ul,li)
-
类选择器(如:class="head",class="head_logo")
-
ID选择器(如:id="name",id="name_txt")
-
全局选择器(如:*号)
-
组合选择器(如:.head .head_logo,注意两选择器用空格键分开)
-
后代选择器 (如:#head .nav ul li 从父集到子孙集的选择器)
-
群组选择器 div,span,img {color:Red} 即具有相同样式的标签分组显示
-
继承选择器(如:div p,注意两选择器用空格键分开)
-
伪类选择器(如:就是链接样式,a元素的伪类,4种不同的状态:link、visited、active、hover。)
-
字符串匹配的属性选择符(^ $ *三种,分别对应开始、结尾、包含)
-
子选择器 (如:div>p ,带大于号>)
-
CSS 相邻兄弟选择器器 (如:h1+p,带加号+)
- !important > 行内样式>ID选择器 > 类选择器 > 标签 > 通配符 > 继承 > 浏览器默认属性
- 计算方法(数字之表达一个**)
- 内联样式表的权值为 1000
- ID 选择器的权值为 100
- Class 类选择器的权值为 10
- HTML 标签选择器的权值为 1
选择器 | 例子 | 例子描述 | CSS |
---|---|---|---|
.class | .intro | 选择 class="intro" 的所有元素。 | 1 |
#id | #firstname | 选择 id="firstname" 的所有元素。 | 1 |
* | * | 选择所有元素。 | 2 |
element | p | 选择所有 <p> 元素。 | 1 |
element,element | div,p | 选择所有 <div> 元素和所有 <p> 元素。 | 1 |
element element | div p | 选择 <div> 元素内部的所有 <p> 元素。 | 1 |
element>element | div>p | 选择父元素为 <div> 元素的所有 <p> 元素。 | 2 |
element+element | div+p | 选择紧接在 <div> 元素之后的所有 <p> 元素。 | 2 |
[attribute] | [target] | 选择带有 target 属性所有元素。 | 2 |
[attribute=value] | [target=_blank] | 选择 target="_blank" 的所有元素。 | 2 |
[attribute~=value] | [title~=flower] | 选择 title 属性包含单词 "flower" 的所有元素。 | 2 |
[attribute|=value] | [lang|=en] | 选择 lang 属性值以 "en" 开头的所有元素。 | 2 |
:link | a:link | 选择所有未被访问的链接。 | 1 |
:visited | a:visited | 选择所有已被访问的链接。 | 1 |
:active | a:active | 选择活动链接。 | 1 |
:hover | a:hover | 选择鼠标指针位于其上的链接。 | 1 |
:focus | input:focus | 选择获得焦点的 input 元素。 | 2 |
:first-letter | p:first-letter | 选择每个 <p> 元素的首字母。 | 1 |
:first-line | p:first-line | 选择每个 <p> 元素的首行。 | 1 |
:first-child | p:first-child | 选择属于父元素的第一个子元素的每个 <p> 元素。 | 2 |
:before | p:before | 在每个 <p> 元素的内容之前插入内容。 | 2 |
:after | p:after | 在每个 <p> 元素的内容之后插入内容。 | 2 |
:lang(language) | p:lang(it) | 选择带有以 "it" 开头的 lang 属性值的每个 <p> 元素。 | 2 |
element1~element2 | p~ul | 选择前面有 <p> 元素的每个 <ul> 元素。 | 3 |
[attribute^=value] | a[src^="https"] | 选择其 src 属性值以 "https" 开头的每个 <a> 元素。 | 3 |
[attribute$=value] | a[src$=".pdf"] | 选择其 src 属性以 ".pdf" 结尾的所有 <a> 元素。 | 3 |
[attribute*=value] | a[src*="abc"] | 选择其 src 属性中包含 "abc" 子串的每个 <a> 元素。 | 3 |
:first-of-type | p:first-of-type | 选择属于其父元素的首个 <p> 元素的每个 <p> 元素。 | 3 |
:last-of-type | p:last-of-type | 选择属于其父元素的最后 <p> 元素的每个 <p> 元素。 | 3 |
:only-of-type | p:only-of-type | 选择属于其父元素唯一的 <p> 元素的每个 <p> 元素。 | 3 |
:only-child | p:only-child | 选择属于其父元素的唯一子元素的每个 <p> 元素。 | 3 |
:nth-child(n) | p:nth-child(2) | 选择属于其父元素的第二个子元素的每个 <p> 元素。 | 3 |
:nth-last-child(n) | p:nth-last-child(2) | 同上,从最后一个子元素开始计数。 | 3 |
:nth-of-type(n) | p:nth-of-type(2) | 选择属于其父元素第二个 <p> 元素的每个 <p> 元素。 | 3 |
:nth-last-of-type(n) | p:nth-last-of-type(2) | 同上,但是从最后一个子元素开始计数。 | 3 |
:last-child | p:last-child | 选择属于其父元素最后一个子元素每个 <p> 元素。 | 3 |
:root | :root | 选择文档的根元素。 | 3 |
:empty | p:empty | 选择没有子元素的每个 <p> 元素(包括文本节点)。 | 3 |
:target | #news:target | 选择当前活动的 #news 元素。 | 3 |
:enabled | input:enabled | 选择每个启用的 <input> 元素。 | 3 |
:disabled | input:disabled | 选择每个禁用的 <input> 元素 | 3 |
:checked | input:checked | 选择每个被选中的 <input> 元素。 | 3 |
:not(selector) | :not(p) | 选择非 <p> 元素的每个元素。 | 3 |
::selection | ::selection | 选择被用户选取的元素部分。 | 3 |
px像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。
em是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。
- em的值并不是固定的
- em会继承父级元素的字体大小
rem是CSS3新增的一个相对单位(root em,根em) Tip dpr => scale
if (!dpr && !scale) {
var isAndroid = win.navigator.appVersion.match(/android/gi);
var isIPhone = win.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = win.devicePixelRatio;
if (isIPhone) {
// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
dpr = 3;
} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
dpr = 2;
} else {
dpr = 1;
}
} else {
// 其他设备下,仍旧使用1倍的方案
dpr = 1;
}
scale = 1 / dpr;
}
- 修改原数组的方法
- pop() 删除最后一个元素
- push() 在末尾插入元素
- shift() 删除第一个元素
- unshift() 在头部插入元素
- reverse() 反转数组
- splice() 删除数组
- sort() 排序
- 不修改原数组的方法
- concat() 连接多个数组,返回一个副本(新数组)
- join() 连接数组内如,返回一个字符串
- slice() 从某个已有的数组返回选定的元素
- toSource() 返回该对象的源代码
- toLocaleString() 把数组转换为本地数组,并返回结果
- valueOf() 返回数组对象的原始值
- API所有方法都不会修改原字符串
- number,string,undefined,null,boolean,symbol
- object,Array,Function,Dat,RegExp
- 6种 number,string,undefined,object,function
- 箭头函数不能作为构造函数,不能使用new
- 箭头函数没有自己的this,他的this是捕获上下文的this
- 箭头函数没有arguments,但是可以使用rest参数
- 箭头函数通过 call() 或 apply() 方法调用一个函数时,只传入了一个参数,对 this 并没有影响(修改不了this)
- 箭头函数没有原型属性
- 每个函数都有自己的显示原型属性 prototype
- 每个引用类型(函数,数组,对象)都拥有__proto__属性,这个称之为隐式原型。
- 每个引用类型的隐式原型都指向它的构造函数的显示原型,隐式原型的constructorj就是他的构造函数
- 显示原型又有隐式原型,以此类推一直到null
function Animal(name){
this.name = name;
}
Animal.eat =fucntion(food){
console.log(food);
}
function Cat(){
}
Cat.prototype = new Animal();
Cat.protyotype.name = 'cat';
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.eat('fish'));
function Cat(name='Tom'){
Animal.call(this);
this.name = name;
}
// Test Code
var cat = new Cat();
console.log(cat.name);
function Cat(name='Tom'){
Animal.call(this);
this.name = name;
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
// Test Code
var cat = new Cat();
console.log(cat.name);
//优化
function Cat(name='Tom'){
Animal.call(this);
this.name = name;
}
Cat.prototype = Animal.prototype;
Cat.prototype.constructor = Cat;
class eventObs {
constructor(){
this.handleFunc={}
}
add(type,func){
if(this.handleFunc[type]){
if(this.handleFunc[type].indexOf(func)===-1){
this.handleFunc[type].push(func);
}
}else{
this.handleFunc[type]=[func];
}
};
fire(type,func){
try{
if(arguments.length===1) {
let target = this.handleFunc[type];
let count = target.length;
for (var i = 0; i < count; i++) {
target[i]();
}
}else{
let target = this.handleFunc[type];
let index=target.indexOf(func);
if(index===-1)throw error;
func();
}
return true;
}catch (e){
console.error('error');
return false;
}
};
remove(type,func){
try{
let target = this.handleFunc[type];
let index=target.indexOf(func);
if(index===-1)throw error;
target.splice(index,1);
}catch (e){
console.error('error');
}
};
once(type,func) {
this.fire(type, func)?
this.remove(type, func):null;
}
}
引用自:https://www.jianshu.com/p/10a20df72bf2
- 请求报文
- 请求行(请求方式,URL,http版本)
- 请求头(各种属性,cookie,accept,if-modified-since)
- 换行
- 请求数据
- 响应报文
- 响应行(http版本,状态码+描述)
- 响应头
- 响应体
- 请求头
- Accept: 浏览器可接受的MIME类型。
- Authorization:授权信息,通常出现在对服务器发送的WWW-Authenticate头的应答中。
- If-Modified-Since:客户机通过这个头告诉服务器,资源的缓存时间。只有当所请求的内容在指定的时间后又经过修改才返回它,否则返回304“Not Modified”应答。
- Referer:客户机通过这个头告诉服务器,它是从哪个资源来访问服务器的(防盗链)。
- User-Agent:User-Agent头域的内容包含发出请求的用户信息。
- Cookie:客户机通过这个头可以向服务器带数据,这是最重要的请求头信息之一。
- Host
- Connection:Keep-Alive
- Cache-Control
- Content-Type (application/x-www-form-urlencoded/text/xml)
- 响应头
- Allow:服务器支持哪些请求方法(如GET、POST等)
- Allow:服务器支持哪些请求方法(如GET、POST等)
- Access-Control-Allow-Origin
- Cache-Control
- ETag
- Expires
- Last-Modified
- Server
- Set-Cookie
- 强缓存
- expires (http 1.0)
标准格林威治(GMT)时间,如果发送请求的时间在expires之前,那么本地缓存始终有效,否则就会发送请求到服务器来获取资源。
expires 的一个缺点就是,返回的到期时间是服务器端的时间,这样存在一个问题,如果客户端的时间与服务器的时间相差很大,那么误差就很大。 - Cache-Control (http1.1)
主要是利用该字段的max-age值来进行判断,它是一个相对值;资源第一次的请求时间和Cache-Control设定的有效期,计算出一个资源过期时间,再拿这个过期时间跟当前的请求时间比较,如果请求时间在过期时间之前,就能命中缓存,否则就不行- no-cache:不使用本地缓存。需要使用缓存协商,先与服务器确认返回的响应是否被更改,如果之前的响应中存在ETag,那么请求的时候会与服务端验证,如果资源未被更改,则可以避免重新下载。
- no-store:直接禁止游览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源。
- public:可以被所有的用户缓存,包括终端用户和CDN等中间代理服务器。
- private:只能被终端用户的浏览器缓存,不允许CDN等中继缓存服务器对其缓存。
- Tip:Cache-Control > expires
- 命中返回200(from cache)
- expires (http 1.0)
- 协商缓存
- Last-Modified/If-Modified-Since
二者的值都是GMT格式的时间字符串 - Etag/If-None-Match
这两个值是由服务器生成的每个资源的唯一标识字符串,只要资源有变化就这个值就会改变 - 命中返回304(not modified)
- Last-Modified/If-Modified-Since
- 1.0和1.1
- 1.0需要keep-alive参数来告知服务器端要建立一个长连接,而HTTP1.1默认支持长连接
- 1.1中新增了24个错误状态响应码
- 1.0没有Host
- 1.1支持只发送header信息(不带任何body信息),节约带宽
- 1.1增加了缓存处理方式 ETag
- 1.1和2.0
- 1.1不支持数据压缩,2.0支持
- 2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级。
- 2.0的web server请求数据的时候,服务器会顺便把一些客户端需要的资源一起推送到客户端,免得客户端再次创建连接发送请求到服务器端获取。
-
HTTPS协议需要到CA申请证书,一般免费证书很少,需要交费。
-
HTTP协议运行在TCP之上,所有传输的内容都是明文,HTTPS运行在SSL/TLS之上,SSL/TLS运行在TCP之上,所有传输的内容都经过加密的。
-
HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
-
HTTPS可以有效的防止运营商劫持,解决了防劫持的一个大问题。
-
Tip CA证书获取过程
- 服务器生成公私钥发给CA机构
- CA机构生成公私钥,然后用私钥对后端的公钥加密并生成CA证书
- CA机构将生成的CA证书返回给服务器
- 浏览器内置CA证书和CA的公钥
- OPTIONS
OPTIONS方法是用于请求获得由Request-URI标识的资源在请求/响应的通信过程中可以使用的功能选项。通过这个方法,客户端可以在采取具体资源请求之前,决定对该资源采取何种必要措施,或者了解服务器的性能。
这个方法很有趣,但极少使用。它用于获取当前URL所支持的方法。若请求成功,则它会在HTTP头中包含一个名为“Allow”的头,值是所支持的方法,如“GET, POST”。 - GET
- HEAD
- POST
- PUT
- DELETE
- TRACE
TRACE方法是用来调用一个远程的请求信息应用程序层的循环后退。最后的请求容器应该像一个200回复实体主体那样反映顾客接受返回的信息。最后的容器或者是原服务器或者是第一代理器或接收在请求中一个Max-Forwards 零数位的网关 - CONNECT
CONNECT这个方法的作用就是把服务器作为跳 板,让服务器代替用户去访问其它网页,之后把数据原原本本的返回给用户。
- dom的本质:浏览器的概念,用js对象来表示页面上的元素,并提供了操作dom对象的API
- 虚拟dom:指的是用js对象的形式,来模拟页面上Dom嵌套关系。(以js对象的形式存在的)
- 虚拟dom的目的:实现页面元素的高效更新
- tree diff:新旧两棵dom树,dom层逐级对比完毕,则所有需要被按需更新的元素,必然能够找到。
- component diff:在进行tree diff的时候,每一层中组件级别的对比,叫做component diff,
- 如果对比前后组件类型相同,则暂时认为此组件不需要被更新;
- 如果对比前后组件类型不同,则需要移除旧组件,创建新组件,并追加到页面上。
- element diff 在进行组件对比的时候,如果两个组件类型相同,则需要进行元素级别的对比。
当创建 Vue 实例时,vue 会遍历 data 选项的属性,利用 Object.defineProperty 为属性添加 getter 和 setter 对数据的读取进行劫持(getter 用来依赖收集,setter 用来派发更新),并且在内部追踪依赖,在属性被访问和修改时通知变化。 每个组件实例会有相应的 watcher 实例,会在组件渲染的过程中记录依赖的所有数据属性(进行依赖收集,还有 computed watcher,user watcher 实例),之后依赖项被改动时,setter 方法会通知依赖与此 data 的 watcher 实例重新计算(派发更新),从而使它关联的组件重新渲染。
vue中循环需加 :key=“唯一标识” ,唯一标识可以使item里面id index 等,因为vue组件高度复用增加key可以标识组件的唯一性,为了更好地区别各个组件key的作用主要是为了高效的更新虚拟DOM。
目前在浏览器环境中这一功能的实现主要有2种方式,Hash模式和History模式
- 1、Hash模式:hash(#)是URL 的锚点,代表的是网页中的一个位置,单单改变#后的部分,浏览器只会滚动到相应位置,不会重新加载网页,也就是说 #是用来指导浏览器动作的,对服务器端完全无用,HTTP请求中也不会不包括#;同时每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用”后退”按钮,就可以回到上一个位置;
- 2、History模式:HTML5 History API提供了一种功能,能让开发人员在不刷新整个页面的情况下修改站点的URL,就是利用 history.pushState API 来完成 URL 跳转而无须重新加载页面
const Foo = () => Promise.resolve({ /* 组件定义对象 */ })
- computed 本质是一个惰性求值的观察者。
- computed 内部实现了一个惰性的 watcher,也就是 computed watcher,computed watcher 不会立刻求值,同时持有一个 dep 实例。
- 其内部通过 this.dirty 属性标记计算属性是否需要重新求值。
- 当 computed 的依赖状态发生改变时,就会通知这个惰性的 watcher,
- computed watcher 通过 this.dep.subs.length 判断有没有订阅者, 有的话,会重新计算,然后对比新旧值,如果变化了,会重新渲染。(Vue 想确保不仅仅是计算属性依赖的值发生变化,而是当计算属性最终计算的值发生变化时才会触发渲染 watcher 重新渲染,本质上是一种优化。) 没有的话,仅仅把 this.dirty = true。(当计算属性依赖于其他数据时,属性并不会立即重新计算,只有之后其他地方需要读取属性的时候,它才会真正计算,即具备 lazy(懒计算)特性。)
在官方文档中,强调了computed区别于method最重要的两点:
- computed是属性调用,而methods是函数调用
- computed带有缓存功能,而methods不是
- computed 计算属性 : 依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值。
- watch 侦听器 : 更多的是「观察」的作用,无缓存性,类似于某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作。