知识总结

一、什么是SPA,及他的优缺点

SPA:single page application  单页面应用    仅在web页面初始化时加载相应的HTML、JavaScript和CSS。一旦加载完成,不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是路由机制实现内容的变换、UI与用户的交互,避免页面的重新加载。

优点:【1】体验好、快    【2】相对服务器压力小       【3】前后端职责分离

缺点:【1】首屏首次加载慢        【2】不利于SEO(搜索引擎优化)

二、new Vue() 发生了什么

创建vue实例,它内部执行了根实例的初始化过程

1.initMixin(Vue)    //实现init函数    [1].合并配置项,如路由,状态管理,渲染函数等;[2].initLifecycle(vm)//初始化$parent,$root,$children,$refs;初始化生命周期  [3].initEvents(vm)//处理父组件传递的监听器; 初始化事件   [4].initRender(vm)//slots,$scopedSlots,_c(),$createElement(); 初始化渲染   [5].callHook(vm, 'beforeCreate'); 调用生命周期钩子函数   [6].initInjections(vm)//获取注入数据,隔代传值;初始化Injections    [7].initState(vm)//初始化props,data,methods,computed,watch;      [8].initProvide(vm)//提供注入数据  初始化Provide       [8]//callHook(vm, 'created')     调用生命周期钩子函数

初始化工作完成后,判断用户是否传入el选项,如果传入调用$mount函数进入模板编译与挂载阶段;如果没有传入el选项,则不进入下一个生命周期阶段,需要用户手动执行

总结:主要逻辑:合并配置,调用一些初始化函数,触发生命周期钩子函数,调用$mount开启下一个阶段

三、Vue.use是干啥的,原理是啥

用来使用插件的,可以在插件中扩展组件、指令、方法等

原理:

1.检查是否已经注册,如果已经注册,则跳出

2.处理入参

3.执行注册方法,调用定义好的install方法,传入处理好的参数,如果没有install方法并且插件本身为function则直接进行注册

四、请说一下响应式数据的理解

核心是观察者模式。数据是被观察的一方,发生改变时,通知所有的观察者。

1.Object:通过Object.defineProperty方法来实现的

    【1】.data通过observe(Object.defineProperty方法)转换成getter/setter的形式来追踪变化

    【2】.当外界通过watcher(观察者)读取数据时,触发getter从而将watcher添加到依赖中

    【3】.当数据发生变化时,触发setter,从而向Dep中的依赖(watcher)发送通知

    【4】.watcher接受到通知后,会向外界发送通知,从而触发视图更新等。

2.数组同上,不同点在于它没有Object.defineProperty方法,它的setter方法是通过重写方法来实现的

注意:Proxy与Object.defineProperty 优劣对比

Proxy优点:1.可以直接监听对象而非属性(Object.defineProperty只能监听属性)    2.可以直接监听数组的变化(Object.defineProperty不能监听数组变化)    3.有多种拦截方法(Object.defineProperty不具备拦截方法)    4.返回的是一个新的对象,我们可以直接操作这个新的对象(Object.defineProperty只能遍历属性修改)

Object.defineProperty优点:兼容性好

五、虚拟DOM

1.简介:通过js描述的DOM结点,

2.why: 操作真实的DOM很耗性能

3.vue 通过vnode类来实例化不同的dom结点。通过补缴差异化的结点来渲染,以节约性能

4.Dom-Diff算法 patch过程---》以新的VNode为基准,改造旧的oldVNode使之成为跟新的VNode一样,这就是patch过程要干的事

5.虚拟DOM过程就是render函数结果VNode到视图显示的过程

六、模板编译

把用户写的模板进行编译,就会产生VNode。模板编译过程就是把用户写的模板经过一系列处理最终生成render函数的过程。

AST:抽象语法树

实施流程:模板解析阶段------>优化阶段------>代码生成阶段

模板解析阶段:<template></template>标签内的模板使用正则等方式解析成抽象语法树(AST)    包括(1)parseHTML HTML解析器(2)parseText 文本解析(3)parseFilters 过滤器解析

优化阶段:(1)在AST中找到所有静态结点并打上标记    (2)在AST中找到所有静态根结点并打上标记

代码生成阶段:根据模板对应的抽象语法树AST生成一个函数,通过调用这个函数就可以得到模板对应的虚拟DOM

七、Vue的生命周期方法有哪些?一般在哪一步发起请求及原因

初始化阶段:为Vue实例上初始化一些属性,事件以及相应式数据      包含的方法:  new Vue()     beforeCreate    create

模板编译阶段:将模板编译成渲染函数

挂载极端:将实例挂载到指定的DOM上,及将模板渲染到真实的DOM上    包含的方法:beforeMount    mounted    beforeUpdate    update

销毁阶段:将实例自身从父组件中删除,并消除依赖追踪及事件监听器        包含的方法:beforeDestory    destoryed


总共分为8个阶段:创建前/后,载入前/后,更新前/后,销毁前/后。

1.创建前/后:

    [1].beforeCreate阶段:vue实例的挂载el和数据对象data都是undefined,还没有初始化    data、methods、computed、watch上的数据和方法不能被访问

    [2].created阶段:vue实例的数据对象data有了,el还没有    可以做一些初始数据的获取

2.载入前/后: 

    [1].beforeMount阶段:vue实例的el和数据对象data都初始化了,还没有挂载之前为虚拟的dom结点    当前阶段虚拟Dom已经创建完成,即将开始渲染。在此时也可以对数据更改,不会触发updated。  

    [2].mounted阶段:vue实例挂载完成,data.message成功渲染。    真实的Dom挂载完毕,数据完成双向绑定,可以访问到Dom结点,使用$refs属性对Dom进行操作。

3.更新前/后:    

     [1].beforeUpdate阶段:数据更新时调用,虚拟DOM打补丁之前,更新之前访问现有的DOM,比如手动一处已添加的事件监听器。    可以更改数据,不会造成重渲染  

    [2].updated阶段:虚拟DOM重新渲染和打补丁后,避免在这个阶段操作数据,防止死循环。

4.销毁前/后:   

    [1].beforeDestory阶段:实例销毁前调用,还可以用,this能获得实例,用于销毁定时器,解绑事件    

     [2].destoryed阶段:实例销毁后调用,调用后所有事件监听会被移除,所有的子实例都会被销毁

第一次页面加载顺序:beforeCreate ----> created ----> beforeMounted ----> mounted

可以在created中请求数据,如果需要页面加载完成之后的条件的话,可以在mounted中请求

八、生命周期钩子是如何实现的

生命周期钩子函数就是回调函数,当创建组件实例的过程中会调用对应的钩子函数

九、Vue的父组件和子组件生命周期执行顺序

第一次页面加载顺序:beforeCreate ----> created ----> beforeMounted ----> mounted

父子mount:    父beforeCreate ----> 父created ----> 父beforeMounted ----> 子beforeCreate ----> 子created ----> 子beforeMounted ----> 子mounted ----> 父mounted

父子update:    父beforeUpdate ---->  子beforeUpdate ---->  子update ---->  父update

父/子update:    父/子beforeUpdate ---->  父/子update

父子destory:        父beforeDestory ---->  子beforeDestory ---->  子destoryed ----> 父destoryed

总结:父组件等待子组件完成后,才执行自己对应完成的钩子

十、数据相关的方法

1.$watch方法

data () {a: 1,b: 2,c: {d: 3,e: 4}}

两种监听方法:

[1].第一种:

 this.$watch(() => this.a + this.b,(newVal, oldVal) => {console.log('newVal:', newVal, '  oldVal:', oldVal)})

或者

this.$watch('a',(newVal, oldVal) => {console.log('newVal:', newVal, '  oldVal:', oldVal)})

setTimeout(() => {this.a = 111}, 1000)

[1].第二种:

watch: {a (val) {console.log('a:', val)}},

2.$set方法

this.c.d=100    =>     this.$set(this.c, 'd', 100)

3.$delete方法

this.$delete(this.c, 'd')

十一、事件相关方法

vm.$on(event,callback)  监听当前实例的自定义事件       

vm.$emit(eventName,[...args])  触发当前实例上的事件      

vm.$off([event,callback])   移除自定义事件监听    1.如果没有参数,移除所有的监听    2.如果只提供事件,则移除该事件所有监听    3.如果同时提供了事件与回调,则只移除这个回调的监听器      

vm.$once(event,callback)    监听一个自定义事件,只触发一次。一旦触发,监听器就移除

十二、生命周期相关方法

1.vm.$mount([elementOrSelector])

作用:如果Vue实例在实例化时没有收到el选项,则它处于“未挂载”状态,没有关联的DOM元素。可以使用vm.$mount()手动地挂载一个未挂载的实例。如果没有提供elementOrSelector参数,模板将被渲染为文档之外的元素,并且你必须使用原生DOM API把它插入文档中。这个方法返回实例本身,因此可以链式调用其他实例方法。

2.vm.$forceUpdate()

作用:迫使Vue实例重新渲染。注意它仅仅影响实例本身和插槽内容的子组件,而不是所有子组件

3.vm.$nextTick([callback])

用法:将回调延迟到下次DOM更新循环后执行。在修改数据后立即使用它,然后等待DOM更新

JS的运行机制:JS执行的是单线程,它是基于事件循环的。

1.所有同步任务都在主线程上执行,形成一个执行栈。

2.主线程之外,还存在一个“任务队列”。只要异步任务有了结果,就在“任务队列”之中放置一个事件。

3.一旦“执行栈”中所有的同步任务执行完毕,系统就会读取“任务队列”。那些对应的异步任务,结束等待状态,进入执行栈,开始执行。

4.主线程不断重复上面第三部。

4.vm.$destroy()

用法:完全销毁一个实例。清理它与其他实例的连接,解绑它的全部指令及事件监听器。

十三、Vue中的组件的data 为什么是一个函数

组件中的data写成一个函数,数据以函数返回值形式定义,这样复用一次组件,就返回一份新的data,类似于给每个组件实例创建一个私有的数据空间,让各个组件维护自己的数据。而单纯的写成对象形式,就使得所有组件实例公用一份data,就会造成一个变,全都会变得结果。

十四、组件间的通信有哪几种

父子组件通信、隔代组件通信、兄弟组件通信

1.props/$emit 适用于父子间通信

2.ref于$parent/$children 适用于父子间通信

3.EventBus($emit/$on)  适用于父子、隔代、兄弟间通信

4.$attrs/$listeners  适用于隔代通信

5.provide/inject     适用于隔代通信

6.vuex     适用于父子、隔代、兄弟间通信

十五、组件中写name选项有哪些好处

1.可以通过递归找到组件

2.通过name属性实现缓存功能(keep-alive)

3.通过name识别组件(跨组件通信)

十六、keep-alive 平时使用在哪里?原理?

主要用于组件缓存,采用LRU算法。最近最久未使用法。

常用include/exclude,允许组件有条件缓存

通过生命周期activated/deactivated,得知当前是否是处于活跃状态

十七、Vue.minxin的使用场景和原理

Vue.minxin作用是抽离公共业务逻辑,采用策略模式进行合并,如果混入数据冲突,采用就近原则。

十八、全局API分析

1.Vue.extend(options)

使用基础Vue构造器,创建一个“子类”。参数是一个高寒组件选项的对象。

2.Vue.directive(id,[definition]) 

自定义指令,如同v-model、v-show、v-html

注册或获取全局指令

// 注册 及钩子函数

Vue.directive('my-directive',{bind:function(){},inserted:function(){},update:function(){},componentUpdated:function(){},unbind:function(){}})

// 注册 (指令函数)

Vue.directive('my-directive',function(){// 这里将会被 `bind` 和 `update` 调用})

// getter,返回已注册的指令

var myDirective=Vue.directive('my-directive')

3.Vue.filter(id,[definition])

作用:注册或获取全局过滤器

4.Vue.component(id,[definition])

作用:注册或获取全局组件。注册还会自动使用给定的id设置组件的名称

5.Vue.compile(template)

作用:在render函数中编译模板字符串。只在独立构建时有效

6.Vue.observable(object)

用法:让一个对象可响应。vue内部会用它来处理data函数返回的对象。返回的对象可以直接用于渲染函数和计算属性内,并且会在反生改变时触发相应的更新。也可以作为最小化的夸组件状态存储器。

十九、Vue-router有几种钩子函数?具体是什么及执行流程是怎样的?

Vue-router钩子函数的作用:用来拦截导航,让它完成跳转或取消

钩子的分类:全局守卫    路由独享守卫    局部守卫

全局守卫:beforeEach//路由跳转前触发    beforeResolve//路由跳转前触发,beforeEach之后,afterEach之前     afterEach//路由跳转后触发 

路由独享守卫:只能在这个路由下起作用    beforeEnter//beforeEach前调用

局部守卫:组件内执行的钩子函数,相当于为配置路由的组件添加的生命周期钩子函数。beforeRouteEnter ---> beforeRouteUpdate ---> beforeRouteLeave

路由A ---> 路由B 流程:

A组件的 beforeRouteLeave ---> 全局的beforeEach ---> 复用组件的beforeRouteUpdate ---> B路由的beforeEnter ---> B组件的beforeRouteEnter ---> 全局的beforeResolve ---> 导航确认 ---> 全局的afterEach ---> 触发DOM更新 ---> 用创建好的实例用beforeRouteEnter

二十、vue-router两种模式的区别

vue-router有三种模式:hash、history、abstract

1.hash模式:hash + hashChange

hash虽然在URL中,但不被包括在HTTP请求中。hash不会重加载页面,通过监听hash(#)的变化来执行js代码从而改变页面。

window.addEventListener('hashchange',function(){self.urlChange()})

使用URL hash值来作路由,支持所有浏览器,包括不支持HTML5 History Api的浏览器;

2.history模式:history + popState

HTML5推出history API,由pushState()记录操作历史,监听popstate事件来监听到状态变更;

依赖HTML5 History Api和服务器配置。

3.abstract

支持所有JavaScript运行环境,如Node.js服务器端。如果发现没有浏览器的API,路由会自动强制进入这个模式。

二十一、Vue中key的作用和公众原理,及理解

例如:v-for="(item,itemIndex) in tabs" :key="itemIndex"

key的作用主要是为了高效的更新虚拟DOM,其原理是vue在patch过程中通过key可以精准判断两个节点是否是同一个,从而避免频繁更新不同元素,使得整个patch过程更加高效,减少DOM操作量,提高性能。

二十二、Vue中的diff原理

vue的diff算法是平级比较,不考虑跨级比较的情况。内部采用深度递归的方式+双指针的方式进行比较。

二十三、v-if 与 v-for的优先级

1.v-for优先于v-if被解析

2.如果同时出现,每次渲染都是先执行循环条件。比较浪费性能

3.要避免出现这种情况。可以在外层嵌套template,用v-if判断。

4.如果条件出现在循环内部,通过计算提前过滤掉

二十四、v-if与v-show的区别

v-if 条件变成真时,才渲染。

v-show 不管是否是否为真,都要渲染,每次条件改变,只是基于css的display进行切换

所以:v-if用于不需要频繁切换的场景;v-show适用于频繁切换条件

二十五、computed和watch的区别和运用场景

computed:计算属性。依赖其他属性值,并且computed的值有缓存,只有它依赖的属性值发生改变,下一次获取computed的值时才会重新计算computed的值;

watch:监听数据的变化。每当监听数据变化时都会执行回调进行后续操作。

运用场景:

1.当我们需要进行数值计算,并且依赖于其他数据时,应该使用computed,因为可以利用computed的缓存特性,避免每次获取值时,都要重新计算;

2.当我们需要在数据变化时执行异步或开销较大的操作时,应该使用watch,使用watch选项允许我们执行异步操作,限制我们执行该操作的评率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。

二十六、如何理解自定义指令?

从编译原理 => 代码生成 => 指令钩子实现 来概述

1.在生成ast语法树时,遇到指令会给当前元素添加directives属性

2.通过genDirextives生成指令代码

3.在patch前将指令的钩子提取到cbs中,在patch过程中调用对应的钩子

4.当执行指令对应的钩子函数时,调用对应指令定义的方法

二十七、V-model的原理是什么?

v-model本质就是一个语法糖,可以看成是value+input方法的语法糖。可以通过model书信的prop和event书信来进行自定义。元素的v-model,会根据标签的不同生成不同的事件和属性。

v-model在内部为不同的输入元素使用不同的属性并抛出不同的事件:

1.text和textarea元素使用value属性和input事件

2.checkbox和radio元素使用checked属性和change事件

3.select字段将value作为prop并将change作为事件

二十八、Vue性能优化

1)编码阶段

尽量减少data中的数据,data中的数据会增加getter和setter,会收集对应的watcher

使用key:有利于将旧虚拟结点列表与新虚拟结点相同的结点更新。

使用冻结对象:可以优化页面渲染

使用计算属性:计算属性有缓存,可以减少计算,提高性能

使用v-show代替v-if:避免频繁渲染

SPA页面采用keep-alive缓存组件

使用路由懒加载、异步组件

防抖、节流

第三方模块按需导入

长列表滚动到可视区域动态加载

图片懒加载

2)用户体验

骨架屏

可以使用缓存

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容

  • 本文目录: 1.安装 2.使用vue 3.创建vue实例 4.事件处理 5.基础指令 6.样式绑定 7.表单输入 ...
    前端辉羽阅读 367评论 0 10
  • Vue是一款高度封装的、开箱即用的、一栈式的前端框架,既可以结合webpack进行编译式前端开发,也适用基于gul...
    Hebborn_hb阅读 1,088评论 0 31
  • 本文章总结时间: 2020-11-18 17:39:25 前言:本章节总结都是Vue相关的基础知识点, 在网上看到...
    和泥巴的葫芦娃阅读 768评论 0 9
  • Vue真是太好了 壹万多字的Vue知识点 超详细! 9 ️1⃣️、Vue和其他两大框架的区别 Angular 学习...
    三千繁夢阅读 333评论 0 0
  • Vue.js特性:渐进式技术栈 轻量级的框架 双向数据绑定 指令 插件化 Vue实例书写模板: 访问Vue实例的属...
    猫晓封浪阅读 1,346评论 0 0