The Wayback Machine - https://web.archive.org/web/20210109000444/https://github.com/iu1340/front-end-review
Skip to content
master
Go to file
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 

README.md

前端复习整理

自己整理,想到什么是什么

动画

CSS3动画

  • 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强行实现
    • 不推荐,直接用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 布局(常问)

容器的属性

  • 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属性完全一致。

选择器

选择器种类

  1. 标签选择器(如:body,div,p,ul,li)

  2. 类选择器(如:class="head",class="head_logo")

  3. ID选择器(如:id="name",id="name_txt")

  4. 全局选择器(如:*号)

  5. 组合选择器(如:.head .head_logo,注意两选择器用空格键分开)

  6. 后代选择器 (如:#head .nav ul li 从父集到子孙集的选择器)

  7. 群组选择器 div,span,img {color:Red} 即具有相同样式的标签分组显示

  8. 继承选择器(如:div p,注意两选择器用空格键分开)

  9. 伪类选择器(如:就是链接样式,a元素的伪类,4种不同的状态:link、visited、active、hover。)

  10. 字符串匹配的属性选择符(^ $ *三种,分别对应开始、结尾、包含)

  11. 子选择器 (如:div>p ,带大于号>)

  12. 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 rem em

px

px像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。

em

em是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。

  • em的值并不是固定的
  • em会继承父级元素的字体大小

rem

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;
}

Array String API

Array API

  • 修改原数组的方法
    • pop() 删除最后一个元素
    • push() 在末尾插入元素
    • shift() 删除第一个元素
    • unshift() 在头部插入元素
    • reverse() 反转数组
    • splice() 删除数组
    • sort() 排序
  • 不修改原数组的方法
    • concat() 连接多个数组,返回一个副本(新数组)
    • join() 连接数组内如,返回一个字符串
    • slice() 从某个已有的数组返回选定的元素
    • toSource() 返回该对象的源代码
    • toLocaleString() 把数组转换为本地数组,并返回结果
    • valueOf() 返回数组对象的原始值

String API

  • API所有方法都不会修改原字符串

js基本数据类型与引用类型

基本数据类型

  • number,string,undefined,null,boolean,symbol

引用类型

  • object,Array,Function,Dat,RegExp

typeof有几种结果

  • 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;

ES6观察者模式,事件绑定,解绑,触发

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

Http

报文结构

  • 请求报文
    • 请求行(请求方式,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)
  • 协商缓存
    • Last-Modified/If-Modified-Since
      二者的值都是GMT格式的时间字符串
    • Etag/If-None-Match
      这两个值是由服务器生成的每个资源的唯一标识字符串,只要资源有变化就这个值就会改变
    • 命中返回304(not modified)

http1.0 http1.1 http2.0

  • 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请求数据的时候,服务器会顺便把一些客户端需要的资源一起推送到客户端,免得客户端再次创建连接发送请求到服务器端获取。

http与https

  • HTTPS协议需要到CA申请证书,一般免费证书很少,需要交费。

  • HTTP协议运行在TCP之上,所有传输的内容都是明文,HTTPS运行在SSL/TLS之上,SSL/TLS运行在TCP之上,所有传输的内容都经过加密的。

  • HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。

  • HTTPS可以有效的防止运营商劫持,解决了防劫持的一个大问题。

  • Tip CA证书获取过程

    • 服务器生成公私钥发给CA机构
    • CA机构生成公私钥,然后用私钥对后端的公钥加密并生成CA证书
    • CA机构将生成的CA证书返回给服务器
    • 浏览器内置CA证书和CA的公钥

HTTP的请求方法OPTIONS

  • OPTIONS
    OPTIONS方法是用于请求获得由Request-URI标识的资源在请求/响应的通信过程中可以使用的功能选项。通过这个方法,客户端可以在采取具体资源请求之前,决定对该资源采取何种必要措施,或者了解服务器的性能。
    这个方法很有趣,但极少使用。它用于获取当前URL所支持的方法。若请求成功,则它会在HTTP头中包含一个名为“Allow”的头,值是所支持的方法,如“GET, POST”。
  • GET
  • HEAD
  • POST
  • PUT
  • DELETE
  • TRACE
    TRACE方法是用来调用一个远程的请求信息应用程序层的循环后退。最后的请求容器应该像一个200回复实体主体那样反映顾客接受返回的信息。最后的容器或者是原服务器或者是第一代理器或接收在请求中一个Max-Forwards 零数位的网关
  • CONNECT
    CONNECT这个方法的作用就是把服务器作为跳 板,让服务器代替用户去访问其它网页,之后把数据原原本本的返回给用户。

VUE相关

虚拟dom
  • dom的本质:浏览器的概念,用js对象来表示页面上的元素,并提供了操作dom对象的API
  • 虚拟dom:指的是用js对象的形式,来模拟页面上Dom嵌套关系。(以js对象的形式存在的)
  • 虚拟dom的目的:实现页面元素的高效更新
diff算法
  • 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

vue中循环需加 :key=“唯一标识” ,唯一标识可以使item里面id index 等,因为vue组件高度复用增加key可以标识组件的唯一性,为了更好地区别各个组件key的作用主要是为了高效的更新虚拟DOM。

VueRouter

目前在浏览器环境中这一功能的实现主要有2种方式,Hash模式和History模式

  • 1、Hash模式:hash(#)是URL 的锚点,代表的是网页中的一个位置,单单改变#后的部分,浏览器只会滚动到相应位置,不会重新加载网页,也就是说 #是用来指导浏览器动作的,对服务器端完全无用,HTTP请求中也不会不包括#;同时每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用”后退”按钮,就可以回到上一个位置;
  • 2、History模式:HTML5 History API提供了一种功能,能让开发人员在不刷新整个页面的情况下修改站点的URL,就是利用 history.pushState API 来完成 URL 跳转而无须重新加载页面

路由懒加载

const Foo = () => Promise.resolve({ /* 组件定义对象 */ })

computed 的实现原理

  • 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区别于method最重要的两点:

  • computed是属性调用,而methods是函数调用
  • computed带有缓存功能,而methods不是
computed是在HTML DOM加载后马上执行的,如赋值;而methods则必须要有一定的触发条件才能执行,如点击事件。

computed 和 watch 有什么区别及运用场景?

  • computed 计算属性 : 依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值。
  • watch 侦听器 : 更多的是「观察」的作用,无缓存性,类似于某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作。

About

前端复习,问题随机整理,想到什么整理什么

Topics

Resources

Releases

No releases published

Packages

No packages published

Languages

You can’t perform that action at this time.