一.CSS
1.什么是BFC?
BFC全称是Block Formatting Context,即块格式化上下文。是关于css渲染定位的一个概念。
BFC(Block formatting contexts):块级格式上下文、IFC(Inline formatting contexts):内联格式上下文、GFC(GrideLayout formatting contexts):网格布局格式化上下文、FFC(Flex formatting contexts):自适应格式上下文 )
先看看视觉格式化模型:用来处理文档并将它显示在视觉媒体的机制,也是css中的一个概念。视觉格式化模型定义了盒(box)的生成,盒主要包括块盒、行内盒、匿名盒以及一些实验性的盒。盒的类型由display属性决定。
块盒(display:block) :块级盒参与快格式化上下文,视觉上呈现为快,单独占一行,每个块级元素至少生成一个块级盒。
行内盒(display:inline,inline-block,inline-table):行内元素生成行内级盒。
匿名盒:匿名块盒和匿名行内盒,因为没有名字,不能利用选择器来选择它们。
三个定位方案: 在定位的时候,浏览器就会根据元素的盒类型和上下文对这些元素进行定位,可以说盒就是定位的基本单位。定位的三种方案:常规流、浮动、绝对定位
常规流
- 在常规流中,盒一个接着一个排列;
- 在块级格式化上下文里,它们竖着排列;在行内格式化上下文,它们横着排列;
- 当position为static或relative,并且float为none时,会触发常规流;
- 静态定位,盒的位置是常规流布局里的位置;相对定位,盒偏移位置由这些属性定义 top,bottom,left和right。即使有偏移,仍然保留原来的位置,其他常规流不能占用位置。
浮动
- 盒称为浮动盒;
- 它位于当前行的开头或末尾;
- 这导致常规流环绕在他的周边,除非设置clear属性。
绝对定位
- 绝对定位方案,盒从常规流中被移除,不影响常规流的布局;
- 它的定位相对于它的包含块,相关css属性:top,bottom,left和right;
- 如果元素的属性position为absolute或fixed,它是绝对定位元素;
- 对于position:absolute,元素定位将相对于最近的一个relative、fixed或absolute的父元素,如果没有则相对于body。
块格式化上下文
块格式化上下文是页面css视觉渲染的一部分,用于决定块盒子的布局及浮动相互影响范围的一个区域。 BFC的创建方法(触发条件):
- 根元素或其他包含它的元素;
- 浮动(元素的float不为none);
- 绝对定位元素(元素的position为absolute或fixed);
- 行内块inlines-block(元素的display:inlines-block);
- 表格单元格(元素的display:table-cell,HTML表格单元格默认属性);
- overflow的值不为visible的元素;
- 弹性盒flex boxes(元素的display:flex或inline-flex);
BFC渲染规则:
- BFC垂直方向边距重叠。
- BFC的区域不会与浮动元素的盒子重叠。
- BFC是一个独立的容器,外面的元素不会影响里面的元素。
- 计算BFC高度的时候浮动元素也会参与计算。
其中,最常见的就是overflow:hidden、float:lef/right、position:absolute。也就是说,每次看到这些属性的时候,就代表了该元素已经创建了一个BFC了。
BFC的范围包含创建该上下文元素的所有子元素,但不包括创建了新BFC的子元素的内部元素。从另一个角度说明,一个元素不能同时存在于两个BFC中。
BFC最重要的效果是,让处于BFC内部的元素与外部的元素相互隔离,使内外元素的定位不会相互影响,这个利用BFC清除浮动所利用的特性。
BFC最显著的效果就是建立一个隔离的空间,以隔绝空间内外元素间相互的作用。
在实际中,利用BFC可以闭合浮动,防止与浮动元素重叠。同时,由于BFC的隔离作用,可以利用BFC包含一个元素,防止这个元素与BFC外的元素发生margin collapse。
BFC的应用场景
-
防止浮动导致父元素高度塌陷。 元素设置浮动,float:left之后,父元素产生塌陷的效果,找到父元素,添加overflow:hidden即可,同时这也是清除浮动的一种方式。
-
避免外边距折叠。 两个块同一个BFC会造成外部边距折叠,但如果对这两个块分别设置BFC,那么边距重叠的问题就不存在了。
2.一个元素实现水平/垂直居中的方式
水平居中
对于行内元素:text-align:center;
对于确定宽度的块级元素:
- margin:0 auto;width和margin实现。
- 绝对定位和margin-left:-width/2,预设是父元素position:相对。 对于宽度未知的块级元素
- 使用表标签(或直接将块级元素设置变量显示:table),再通过给该标签添加左右边距为auto。
- 显示:inline-block和text-align:center实现水平居中。
- 绝对定位+transform,translateX可以移动本身元素的50%;
- flex布局使用justify-content:center:中心。
垂直居中
- 利用line-hight实现居中,这种方法适合纯文字类。
- 通过设置父容器相对定位,子级设置绝对定位,并通过移位transform实现。
- 弹性布局flex:父级设置display:flex,子级设置margin为auto实现自适应居中。
- flex方案:align-items:center。
3.浮动布局的优缺点?清除浮动有哪种方式?
优点:最初的优点就是在图文混排的时候可以很好的使文字围绕在图片的周围。当元素浮动后,它具有块级元素的一些性质,例如可以设置宽高等。
缺点:浮动元素一旦脱离了文档流,就无法撑起父元素的高度塌陷。
清除浮动的方式:
- 添加额外标签,并且添加clear属性;
- 父级添加overflow:hidden属性,或者设置高度;
- 建立伪类选择器清除浮动:
二.js相关
1.说说你对闭包的理解
就是定义在一个函数内部的函数,内部函数持有外部函数内的变量或参数的引用。内部函数依赖外部函数,外部函数参数和变量不会被垃圾回收机制回收,这些变量始终存在于内存中。
其好处是可以读取函数内部的变量,可以避免全局变量的污染,坏处会增加内存的使用量,容易导致内存泄露,解决方法就是退出函数前,将不适用的局部变量全部删除。在js中,函数即是闭包,只有函数才会产生作用域。
闭包特性,函数嵌套函数,在函数内部可以引用外部的参数和变量,参数和变量不会被垃圾回收机制回收。
由于在js中,变量的作用域属于函数作用域,在函数执行后,作用域就会被清理,内存也会被回收,但是由于闭包就是建立在一个函数内部的子函数,由于子函数可以访问上级作用域的原因,即使上级函数执行完,作用域也不会随之销毁。
在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁
在什么场景使用到闭包函数
- settimeout:原生的settimeout传递的第一个函数不能带参数,通过闭包可以实现传参效果。
- 回调:事件触发时调用的函数。
- 函数防抖:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。实现的关键就在于settimeout这个函数,由于还需要一个变量来保存计时,考虑维护全局纯净,可以借助闭包来实现。
- 封装私有变量。
还有哪些操作会导致内存泄露
- 闭包引起的内存泄露
- 意外的全局变量引起的内存泄露
- 没有清理的dom元素引起的内存泄漏(被遗忘的定时器或者回调函数)
- 子元素存在引用引起的内存泄露
2.说一下防抖和节流
防抖:在事件被触发n秒后再执行回调,如果在这n秒又被触发,则重新计时。(反复触发,只认最后一次,从最后一次触发开始计时。)
节流:规定在一个单位时间内,只能触发一次函数,如果这个单位时间内触发多次函数,只有一次生效。
即:函数防抖和节流都是防止某一时间频繁触发,但是原理不一样。防抖是某一时间内只执行一次,节流是间隔时间执行。
结合应用场景
- 防抖:① search搜索联想,用户在不断输入值时,用防抖来节约请求资源。② window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次。
- 节流:① 鼠标不断点击触发,控制单位时间内只触发一次。② 监听滚动事件,比如是否滑到底部加载更多,用throttle来判断。
3.js的变量类型有哪些?判断类型的方法与其区别?
基本类型:Number、Boolean、String、Null、Underfined、symbol(es6新增的)、BigInt(ES2020)
引用类型:Object、对象子类型(Array、Function)
判断类型的方法:
- 使用typeof能判断出四种,分别是number、string、Boolean、object,剩余的均被检测为object。
- 使用instanceof,根据instanceof的定义:判断参照对象的prototype属性所指向的对象是否在被行测对象的原型链上。这种变量判断可以检测出9种,null和underfined被检测为object,因为js中没有这种全局类型。弊端:对于number、string、Boolean这三种类型,只有通过构造函数(new)定义才能检测出,普通定义是检测不出来的。
- 使用constructor检测,针对instanof的弊端,使用constructor检测,constructor是原型对象的属性指向构造函数。可以检测出除了null和underfined的9种类型。但是弊端是constructor所指向的构造函数是可以被修改的。
- 使用Object.prototype.toString.call,object.prototype.tostring可以取得对象的内部属性(class),并根据这个内部属性返回诸如【object Number】的字符串,那么就可以通过call获取内部属性【class】。
- 使用JQuery的.type是基于ES5的object.prototype.tostring.call进一步封装,可以检测出所有的变量类型。
4.如何判断数组类型
Array.isArray
5.数组去重
- Array.from(new set([1,1,2,3,4]))
- fiflter方法
- 两个for循环
- indexOf
6.箭头函数和普通函数的区别
- 箭头函数是匿名函数,不能作为构造函数,不能使用new;
- 箭头函数不绑定arguments,取而代之用reset参数...解决
- 箭头函数不绑定this,会捕获其所在的上下文的this值,作为自己的this值;
- 箭头函数通过call()或apply()方法调用一个函数时,只传入了一个参数,对this并没有影响;
- 箭头函数没有原型属性。
7.ES5和ES6之间的区别
三.前端性能
1..如何实现图片懒加载
方案一:clientHeight,scrollTop和offsetTop 先给图片一个占位资源:
接着,通过监听scroll事件来判断图片是否到达视口:
对scroll事件做节流处理,以免重复触发:
方案二:getBoundingClientRect 用另一种方法判断图片是否出现在了当前视口,即DOM元素的getBoundingClientRect API 把lazyload函数改成下面这样:
方案三:IntersectionObserver 这是浏览器内置的一个API,实现了监听window的scroll事件,判断是否在视口中以及节流三大功能。
2.一个页面从输入URL到页面加载显示完成,这个过程发生了什么?
- 浏览器会开启一个线程来处理这个请求,对URL分析判断如果是http协议就按照web的方式来处理;
- 调用浏览器内核的对应方法,比如webview中的loadURL方法;
- 通过DNS解析获取网址的ip地址,设置UA等信息发出第二个get请求;
- 进行HTTP协议会话,客户端发生报头(请求报头);
- 进入到web服务器上的web server,如Apache、Tomcat、node.js,找到对应的请求处理;
- 进入部署好的后端应用,如PHP、Java、JavaScript、Python等,找到对应的请求处理;
- 处理结束回馈报头,此处如果浏览器访问通过,缓存上有对应的资源,会与服务器最后修改时间对比,一直则返回304;
- 浏览器开始下载HTML文档(响应报头、状态码200),同时使用缓存;
- 文档树建立,根据标记请求所需指定mime类型的文件(比如css、js),同时设置了cookie;
- 页面开始渲染DOM,js根据DOM API操作DOM,执行事件绑定等,页面显示完成。
3.深入理解(谈谈)浏览器的缓存机制
四.网络协议
1.介绍https握手过程
- 客户端使用https的URL访问web服务器,要求与服务器建立ssl连接;
- web服务器收到客户端请求后,会将网站的证书(包含公钥)传送一份给客户端;
- 客户端收到网站证书后会检查证书的颁发机构及过期时间,如果没有问题就随机产生一个密钥;
- 客户端利用公钥将会话密钥加密,并传输给服务端,服务端利用自己的私钥解密出会话密钥;
- 之后服务器与客户端使用密钥加密传输。
五.浏览器
1.介绍下重绘和回流
2.web本地存储(localStorage、sessionStorage)
说明: 1.对于浏览器来说,使用web storage储存键值对比存储cookie更直观,而且容量更大,它包含两种:localStorage和sessionStorage。 2.sessionStorage(临时存储):为每一个数据源维持一个存储区域,在浏览器打开期间存在,包括页面重新加载。 3.localStorage(长期存储):与sessionStorage一样,但是浏览器关闭后,数据依然存在。
api: sessionStorage和localStorage的用法基本一致,引用类型的值要转换成json。
六.vue相关
1.vue双向绑定的原理是什么?
双向数据绑定是基于object.defineProperty()重新定义get和set方法实现的。修改触发set方法赋值,获取触发get方法取值,并通过数据劫持发布信息。
2.vue组件之间传值
1.父组件与子组件之间传值
父组件传给子组件:子组件通过props方法接收数据;
子组件传给父组件:$emit方法传递参数
2.非父子组件间的数据传递,兄弟组件传值
eventBus,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。
vuex
通过子传父,父传子
3.vue组件通信有几种方式
- pros和emit(常用): 父组件向子组件传递数据通过prop传递的,子组件传递数据给父组件通过$emit触发事件来做到。
- attrs和listeners:第一种方式处理父子组件之间的数据传输有一个问题:如果父组件A下面有子组件B,组件B下面有组件C,这时如果组件A想传递数据给组件C,采用第一种方式的话,必须让组件A通过prop传递信息给组件B,组件B再通过prop传递信息给组件C;要是组件A和组件C之间有更多的组件,那采用这种方式就很复杂了。listeners能够让组件A之间传递消息给组件C。
- 中央事件总线:以上两种方式都是父子组件之间传递数据,如果不是父子组件,可以使用中央事件总线的方式。新建一个Vue事件Bus对象,然后通过bus.on监听触发的事件。(可用于父子、兄弟、跨级实现组件通信)
- provide和inject:成对出现,用于父级组件向下传递数据。父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量。不论子组件有多深,只要调用了inject,就可以注入provider中的数据。而不是局限于只能从当前父组件的prop属性来获取数据,只要在父组件的生命周期内,子组件都可以调用。(主要解决了跨级组件间的通信问题,使用场景主要是子组件获取上级组件的状态)
- vuex处理组件之间的数据交互。
- 传统的一个方法,通过本地存储sessionSrorage,把数据存到本地,再获取使用。
4.vue的请求拦截器与响应拦截器
请求拦截器:作用是在请求发送前进行一些操作,例如在每个请求里加上token,统一做处理。
关于拦截,前端的请求最终还是离不开ajax,像vue里的vue-resource、axios,都只是对ajax进行了统一的封装,它暴露出来的拦截器就是写了一个方法,把ajax写在方法里。请求拦截器,就是在执行这个方法的时候,先将请求时要添加给请求头的那些数据(token、后端要的加密码等)先执行一遍,都赋值给一个变量,再统一传给ajax,接下来就是执行ajax,这就是所谓的请求拦截。其实就是先执行要添加的数据,然后再执行ajax,如果把这个添加数据的过程抽出来,就成了所谓的请求拦截器。
响应拦截器:作用是在接收到响应后进行一些操作,例如在服务器返回登录状态失效,需要重新登录的时候,跳转到登录页,或者token过期了需要刷新token。
响应拦截器也是如此,在请求结果返回后,先不直接导出,而是先对响应码等进行处理,处理好后再导出给页面,如果将这个响应码的处理过程抽出来,就成了所谓的响应拦截器。
5.vue自定义指令及使用
1.什么是指令
在vue中提供了一些对于页面和数据更为方便的输出,这些操作就叫做指令,已v-xxx表示,比如html页面中的属性v-if。 指令中封装了一些dom行为,结合属性作为一个暗号,暗号有对应的值,根据不同的值,会进行相关的DOM操作的绑定,即可以进行一些模板的操作。
2.vue中常用的内置指令(说说vue里的指令)
①v-text:元素的innerText属性,只能用在双标签中,和{{}}效果是一样的,使用较少。
②v-html:元素的innerHTML,其实就是给元素的innerHTML赋值。
③v-show:元素的显示与隐藏,基于css样式的切换。如果确实要隐藏,会给元素的Style加上display:none。
④v-if:元素的插入与移除操作,相当于对元素的创建和销毁。如果表达式的值为false,会留下一个<!---->作为标记,若未来v-if的值为true了,就在这里插入元素(如果if有else就不要单独留坑了)。
⑤v-else-if:前一个相邻元素必须有v-if或v-else-if。
⑥v-else:前一个相邻元素必须有v-if或v-else-if。
⑦v-for:用于循环渲染一组数据(数组或对象)。必须使用特定语法:v-for="item in list"。注:当v-for与v-if同处于一个节点时,v-for的优先级比v-if高。即v-if将运行在每个v-for循环中。
⑧v-on:主要用于监听dom事件,然后执行一些操作。简写为【@】。
⑨v-model:用于input/textarea等表达控件上创建双向数据绑定。
⑩v-bind:动态的绑定一个或多个属性,常用于绑定class、style、href等。
⑪v-once:组件和元素只渲染一次,当数据发生变化,也不会重新渲染。
v-if和v-show的对比(v-if和v-show有什么区别,v-show其实是加了哪个css属性)
- v-if是真正的条件渲染,因为他会确保在切换过程中条件块内的事件监听器和子组件适当的被销毁和重建。
- v-if也是惰性的,如果在初始渲染时条件为假,则什么也不做,直到条件第一次为真时,才会开始渲染条件块。
- 相比之下v-show就简单得多,不管初始条件是什么,元素总是会被渲染,并且只是简单的基于css进行切换。 一般来说,v-if有更高的切换开销,而v-show更更高的初始渲染开销。因此,如果需要非常频繁的切换,则使用v-show比较好,如果在运行条件时很少改变,则使用v-if比较好。
自定义指令的钩子函数(说说自定义指令,自定义指令的使用场景)
在实际开发过程中,可能这些内置指令并不能满足所有的需要,或者想为元素附加一些特别的功能。这时候就需要用到vue的自定义指令。自定义指令是对普通DOM元素进行底层操作。
vue提供了自定义指令的5个钩子函数
- bind:指令第一次绑定到元素时调用,只执行一次。在这里可以进行一次性的初始化设置。(当指令绑定在HTML元素上触发)
- inserted:被绑定的元素,插入到父节点的DOM中时调用(仅保证父节点存在)。(当指令绑定的元素插入到父节点中的时候触发)
- update:组件更新时调用。(当指令绑定的元素状态/样式、内容(这里指元素绑定的vue数据)发生改变时触发)
- componentUpdated:组件与子组件更新时调用。(当update()执行完毕之后触发)
- unbind:指令与元素解绑时调用,只执行一次。(当指令绑定的元素从dom中删除时触发)
注意:
-
- 除了update与componentUpdated钩子函数外,每个钩子函数都含有el、binding、vnode这三个参数。
-
- 在每个函数中,第一个参数永远是el,表示被绑定了指定的那个DOM元素,这个el参数,是一个原生的js对象,所以 vue自定义指令可以用来直接和DOM打交道。
-
- binding是一个对象,它包含以下属性:name、value、oldValue、expression、arg、modifiers
-
- oldVnode只有在update与componentUpdated钩子中生效。
-
- 除了el之外,binding、vnode属性都是已读的。
指令的注册方式和过滤器、混入、组件注册的方式一样都分为2种:全局注册、局部注册。
6.谈谈路由导航守卫(钩子函数)
vue路由导航守卫,也就是我们常说的生命周期钩子函数,钩子函数的意思就是在特定的时刻,vue会自动触发这个方法,我们可以通过这些个钩子函数,实现一些功能,比如,某些页面需要登录后才能访问,某些页面需要用户达到什么等级才可以访问,又或者是跳转页面后修改一些信息等等,我们就可以通过路由导航守卫来拦截并做相应的处理。
植入路由导航过程的方法: 全局的、单个路由独享的,或者组件级的。
路由的钩子函数总结有6个:
全局的路由钩子函数:beforeEach、afterEach
单个的路由钩子函数:beforeEnter
组件内的路由钩子函数:beforeRouter、beforeRouterLeave、beforeRouterUpdate
模块一:全局导航钩子函数
- vue.router.beforeEach(全局前置守卫):是一个全局的before钩子函数,在每次每一个路由改变的时候都得执行一遍。3个参数:to:(router路由对象)即将要进入的目标;from:当前路由正要导航的路由;next:一定要调用该方法来resolve这个钩子。next(参数/空)。进入管道的下一个钩子。(next('/')或者next({path:'/'}):跳转到一个不同的地址。当前导航被中断,然后进行新的导航) 应用场景:可进行一些页面跳转前处理,比如判断需要登录的页面进行拦截,做登录跳转(就是路由拦截)
2. vue.router.afterEach(全局后置守卫),在页面加载之后
模块二:单个的路由钩子可以在路由配置上直接定义beforenter守卫,与全局前置守卫方法参数一致。
模块三:组价内守卫(组件内钩子)
离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过next(false)来取消。
vue-router路由拦截造成死循环的问题
7.keep-alive实现原理
keep是一个抽象组件:它自身不会渲染一个dom元素,也不会出现在父组件链中;使用keep-alive包裹动态组件时,会缓存不活动的组件示例,而不是销毁他们。
一个场景:用户在某个列表页面选择筛选条件过滤出一份数据列表,由列表页面进入数据详情页面,再返回列表页面,我们希望:列表页面可以保留用户的筛选(或被选中)状态。
keep-alive就是用来解决这种场景。当然keep-alive不仅仅是能够保存页面/组件的状态这么简单,他还可以避免组件反复创建和渲染,有效提升系统性能。总的来说,kee-alive用于保存组件的渲染状态。
keep-alive的用法:
-
在动态组件中的应用
<keep-alive :include="whiteList" :exclude="blackList" :max="amount"> <component :is="currentComponent"></component> </keep-alive> -
在vue-router中的应用
<keep-alive :include="whiteList" :exclude="blackList" :max="amount"> <router-view></router-view> </keep-alive>
include定义缓存白名单,keep-alive会缓存命中的组件;exclude定义缓存黑名单,被命中的组件将不会被缓存;max定义缓存组件上限,超出上限使用LRU的策略置换缓存数据。
exclude的优先级大于include 也就是说:当include和exclude同时存在时,exclude生效,include不生效。 当组件被exclude匹配,该组件将不会被缓存,不会调用activated 和 deactivated。
内存管理的一种页面置换算法,对于在内存中但不用的数据块(内存块)叫做LRU,操作系统会根据哪些数据属于LRU而将其移出内存而腾出空间来加载另外的数据
keep-alive的生命周期钩子:
在被keep-alive包含的组件/路由中,会多出两个生命周期的钩子:activated与deactivated。
activated在组件第一次渲染时会被调用,之后在每次缓存组件被激活时调用。activated调用时机:
deactivated:组件被停用(离开路由)时调用
使用了keep-alive就不会调用beforeDestroy(组件销毁前钩子)和destroy(组件销毁),因为组件没被销毁,被缓存起来了。
8.vue生命周期钩子
每个Vue实例都经历过一系列初始化步骤。从创建时设置数据到编译模板,将实例装载到dom,最后在数据更改期间更新dom。这个过程被称为vue实例的生命周期,在默认情况下,当他们经历创建和更新dom的过程中,会在其中运行一些函数,在这些函数内部创建并声明vue组件,这些函数称为生命周期钩子。
其实大部分生命周期并不会用到,但需要注意:
- ajax请求最好放在created里面,因为此时已经可以访问this了,请求到数据就可以直接放在data里面。(问:ajax请求应该放在哪个生命周期)
- 关于dom的操作要放在mounted里面,在mounted前面访问dom会是underfined。
- 每次进入/离开组件都要做一些事情,用什么钩子: 不缓存:进入的时候可以用created和mounted钩子,离开时用beforeDestroy和destroyed钩子,beforeDestroy可以访问this,destroyed不可以访问this。
缓存了组件: 缓存了组件之后,再次进入组件不会触发beforeCreate、created、beforeMount、mounted,如果你想每次进入组件都做一些事情的话,可以放在activated进入缓存组件的钩子中。
同理:离开缓存组件的时候,beforeDestroy和destroyed并不会触发,可以使用deactivated离开缓存组件的钩子来代替。
触发钩子的完整顺序 将路由导航、keep-alive、和组件生命周期钩子结合起来触发顺序。假设从a组件离开,第一次进入b组件:
- beforeRouterLeave:路由组件的组件离开路由前钩子,可取消路由离开。
- beforeEach:路由全局前置守卫,可用于登录验证、全局路由loading等。
- beforeEnter:路由独享守卫。
- beforeRouterEnter:路由组件的组件进入路由前钩子。
- beforeResolve:路由全局解析守卫。
- afterEach:路由全局后置钩子。
- beforeCreate:组件生命周期,不能访问this。
- created:组件生命周期,可以访问this,不能访问dom。
- beforeMount:组件生命周期。
- deactivated:离开缓存组件a,或者触发a的beforeDestroy和destroyed组件销毁钩子。
- mounted:访问/操作dom。
- activated:进入缓存组件,进入a的嵌套子组件(如果有的话)。
- 执行beforeRouterEnter回调函数next。
9.vue中的组件的data为什么是一个函数?
每次使用组件时都会对组件进行实例化操作,并且调用data函数返回一个对象作为组件的数据源。这样可以保证多个组件间的数据互不影响。
如果data是对象的话,对象属于引用类型,会影响到所有的实例。所以为了保证组件不同的实例之间data不冲突,data必须是一个函数。
10.谈谈webpack的理解
- Entry:入口,webpack执行构建的第一步将从entry开始,可抽象成输入。
- module:模块,在webpack里一切皆可模块,一个模块对应着一个文件。webpack会从配置的Entry开始递归找出所有依赖的模块。
- chunk:代码块,一个chunk由多个模块组合而成,用于代码合并与分割。
- loader:代码转换器,用于把模块原内容按照需求转换成新内容。
- plugin:扩展插件,在webpack构建流程中的特定时机会广播出对应的事件,插件可以监听这些事件的发生,在特定的时机做对应的事情。
- Output:打包后文件输出的位置。