小滴课堂22年新版互联网大厂前端高频面试题(2)~持续更新中

目录

前言

一、Vue的生命周期详解

二、Vue的双向绑定

三、Vue中组件间通信有哪几种⽅式

四、初中级面试题常见谈谈你对var、let、const的理解

五、访问首页的速度很慢,有哪些方法可以提高访问速度?


前言

小滴课堂,旨在让编程不在难学,让技术与生活更加有趣。 随着互联网+的时代,在线教育技术越来越便捷,小滴课堂依托在线教育时间以及空间上的便利,为广大IT从业者提供了更为方便、快捷的学习交流途径、提供大量高质量的IT在线课程。更多教程请访问xdclass.net(添加VX:xdclass99)

一、Vue的生命周期详解

回答

(一)每个Vue实例都有⼀个完整的⽣命周期,当⾯试官提到让你谈谈对Vue的生命周期的理解时,如何回答才是⼀个令⼈满意的回答?
1、第⼀个问题:什么是 Vue 的生命周期?
通俗的来说,⼀个 Vue 实例从创建到销毁的这个过程,我们称之为 Vue 的生命周期。
2、整个流程?
(1)开始创建⼀个 Vue 实例 —> 初始化 Vue 实例内部数据 —> 模板开始编译 —> 挂载并渲染dom
(2)—> 更新数据 ( 可能有这个过程 ) —> Vue 实例开始销毁 —> 实例销毁完毕
(3)整个流程⼤概如上,这个流程⾥, Vue 实例会触发⼀些钩⼦。谈到这,可能有童鞋会有问,什么是钩⼦?
3、什么是钩⼦?
钩⼦,其实是钩⼦函数的简称,说的简单点,就是 Vue 实例的生命周期里,自动会触发的函数,有的话就执⾏这个函数,这也就是我们常说的钩⼦。
(二)简单的概念和流程到此结束,那么Vue组件的⽣命周期⾥,这些钩⼦触发的时候,到底⼲了什么事情?
1、详解触发钩⼦时已完成的操作及建议的操作
(1)beforeCreate
①实例初始化,将 this 指向 Vue 实例,此时 data computed watch methods 上的方法和数据均不能访问
②可在此处加⼊ loading 事件
(2)created
①实例创建完成,完成数据 (data props computed) 的初始化 ,可访问其中的数据。
②此时未挂载 dom ,也不能访问 Vue 实例中的 $el 属性
③没有 dom ,也就是说 $ref 为空数组了
④可以对 data 数据进⾏操作,可进行⼀些请求,请求不易过多,避免⽩屏时间太⻓。
⑤若在此阶段进⾏的 DOM 操作⼀定要放在 Vue.nextTick() 的回调函数中, dom 更新的时候,才会触发nextTick里 的回调函数。
⑥也可在此处结束 loading
(3)berofeMount
①此时 $el 挂载完毕,并且把 Vue 实例中 template 部分编译成 render 函数 , 或者直接执行render 函数
②使用 render 函数的结果和我们之前使⽤ template 解析出来的结果是⼀样的。
③render 函数是发⽣在 beforeMount mounted 之间的,这也从侧面说明了,在beforeMount的时候, $el 还只是我们在 HTML里面 写的节点,然后到 mounted 的时候,它就把渲染出来的内容挂载到了DOM 节点上。这中间的过程其实是执⾏了render函数的内容。
(4)mounted
①完成创建 vm.$el dom 此时已经根据 template 编译的 render 函数,渲染完成
②有了 DOM 且完成了双向绑定 可访问 DOM 节点及 $ref 属性
(5)beforeUpdate( 更新数据时触发 )
数据更新之前,可在更新前访问现有的 DOM, 如⼿动移除添加的事件监听器
(6)updated
①完成虚拟 DOM 的重新渲染
②组件 DOM 已完成更新;
③可执行依赖的 dom 操作
④注意:不要在此函数中操作数据,会陷⼊死循环的。
(7)activated
在使用  vue-router 时,有时我们会使用  keep-alive 标签来保持组件的状态,避免频繁发送请求。此时,created 钩⼦就不会被重复调用了。因此,如果我们需要在组件每次加载的时候进⾏某些操作,可以在activated 这个钩⼦当中触发。
(8)deactivated
keep-alive 标签包住的组件,被移除时触发。
(9)beforeDestroy
①实例销毁之前调用。在这⼀步当中,实例仍然完全可用。
②可做⼀些删除提示,比如, " 您确认离开此页面 "
③可⽤于销毁定时器,解绑全局事件或者销毁引⼊的插件对象
(10)destroyed
Vue 实例销毁后调用。此时 Vue 实例里的数据解除绑定,所有的事件监听器也被移
除了
2、最后丢⼀张官⽹的 Vue生 命周期图解给⼤家巩固下

二、Vue的双向绑定

回答

(一)核心
Object.defifineProperty()方
(二)原理
通过Object.defifineProperty() 来劫持各个属性的 setter getter ,在数据发⽣变动时通知Vue 实例,触发相应的 getter setter 回调函数。当把⼀个普通 Javascript 对象传给Vue 实例来作为它的 data 选项时, Vue 将遍历它的属性,用 Object.defifineProperty 将它们转为 getter/setter 。⽤户看不到 getter/setter ,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。
(三)特点
1、Vue 的数据双向绑定将 MVVM 作为数据绑定的入口,整合 Observer Compile 和Watcher三者,通过 Observer 来监听⾃⼰的 model 的数据变化,通过 Compile 来解析编译模板指令(vue 中是用来解析 {{}} ),最终利用 watcher 搭起 observer Compile 之间的通信桥梁,达到数据变化 —> 视图更新;视图交互变化( input —> 数据 model 变更双向绑定效果。
2、这就是通过数据劫持和发布 - 订阅者功能来实现的
(四)js的简单实现
<body>
    <div id="app">
    <input type="text" id="txt">
    <p id="show"></p>
</div>
</body>
<script type="text/javascript">
    var obj = {}
    Object.defineProperty(obj, 'txt', {
        get: function () {
            return obj
        },
        set: function (newValue) {
            document.getElementById('txt').value = newValue
            document.getElementById('show').innerHTML = newValue
        }
    })
    document.addEventListener('keyup', function (e) {
        obj.txt = e.target.value
    })
</script>

三、Vue中组件间通信有哪几种⽅式

回答

(一)父子组件
1、props/event
子组件有时需要与父组件进行沟通,沟通的方式就是子组件 $emit 传递⼀个自定义事件,父组件通过监听这个事件来做进⼀步动作。而父组件与子组件通信则使用 props 来传递⼀个绑定在子组件上的属性,这个属性值来源于父组件
2、parent/children
(1)父组件中
使用  $children 操作⼦组件。并在父组件通过 $children 访问到已经在在父组件当中引入了的子组件, $children 返回的是子组件列表,是⼀个数组。
(2)子组件中
子组件可通过 $parent 来访问父组件里的数据和定义的方法,如修改父组件中的$data
(3)ref
父组件中可为⼦组件定义⼀个 ref 属性,然后⽗组件⾥通过 $ref[ 对象子组件上定义的属性名 ]来访问子组件里的数据
(4)provide/inject
适用于祖先和后代关系的组件间的通信,祖先元素通过 provide 提供⼀个值,后代元素则通过 inject 获取到这个值。这个值默认是非响应的,如果是对象那么则是响应式的:
(二)兄弟组件
1、bus
(1)在 Vue . 2.x 中, 推荐使⽤⼀个空的 Vue 实例作为中央事件总线( bus ),也就是⼀个中介。
(2)通信的组件必须都引⼊这个实例。
(3)通过 bus.$emit() 传递出⼀个⾃定义事件
(4)在需要进⾏操作的组件⾥,通过 bus.$on 监听这个自定义事件 , 进⾏操作
2、Vuex
(1)Vuex Vue 推出的状态管理⼯具
(2)Vuex 就是把需要共享的变量全部存储在⼀个对象⾥⾯,然后将这个对象放在顶层组件中供其
他组件使用。这么说吧,将 vue 想作是⼀个 js文 件、组件是函数,那么 vuex 就是⼀个全局变量,只是这个“ 全局变量 包含了⼀些特定的规则而已。
(3)通过 $store 这个对象访问数据和调⽤在 Vuex 里 定义的公共⽅法
(三)跨级组件
bus vuex provide inject

四、初中级面试题常见谈谈你对varletconst的理解

回答

(一)var定义的变量,没有块的概念,可以跨块访问,不能跨函数访问,会造成变量提升
(二)let定义的变量,只能在块作⽤域⾥访问,不能跨块访问,也不能跨函数访问。不会造成变量提升
(三)const⽤来定义常量,使⽤时必须初始化(即必须赋值),只能在块作用域里访问,⽽且不能修改。不会造成变量提升
(四)也可以从另⼀个⻆度简单回答(varES6前⽤来定义变量,会造成变量提升。letconst书是ES6才出现的,⼀个⽤来定义变量,⼀个定义常量)
(五)如果上面的回答出来了,⼀般面试官可能会继续深挖
1、你说 const 是⽤来定义常量。使⽤时必须初始化且不能修改,那么下面这段代码运行会造成什么结果
function a () {
        const b ={a:2}
        b.a = 3
        console.log(b)
      }
      a()
2、由于 const 这个时候定义的是⼀个对象,它的内存地址并没改变,所以这个改变内部的属性是允许的,这段代码可以正常运行。这里主要考察你是否是背答案和对复杂数据类型的操作的理解
3、额外知识点,数据存储
(1)存可以分为栈区和堆区
(2)栈区:⽤来存储用基本类型的数据 和 引用类型数据的地址。
(3)堆区:⽤来存储引用类型数据的数据

五、访问首页的速度很慢,有哪些方法可以提高访问速度?

回答

(一)组件懒加载
1、描述
懒加载也叫做延迟加载、按需加载,在非首屏展示的组件或者数据可以使用懒加载
2、特点
(1)减小接口请求个数,⻚⾯的渲染负担
(2)提高首页的展示速度,提升用户体验
(3)防止加载过多图片而影响其他资源文件的加载
3、实现
(1)通过 import() 方 法引⼊组件
import(./test.js).then(({fun})=>{fun()})

()=>import('./Test')
(2)通过监听用户的滚动事件触发来展示非首屏的图⽚
4、懒加载和预加载的区别
(1)懒加载也叫延迟加载,指的是在网页中延迟加载图片的时机,当用户需要访问时,再去加载,可以提高网站的首屏加载速度,提升用户的体验
(2)预加载指的是将所需的资源提前请求加载到本地,这样后⾯在需要用到时就直接从缓存取资源,通过预加载能够减少用户的等待时间,提高用户的体验

(二)非首屏的内容延时渲染实现(直接上代码)

// 定义⼀个异步的函数,当⽤户滑动时则不延时
const delayMS = (ms) => {
  const p = new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
  // 如果⽤户开始滑动,则取消延期
  const onTouchPromise = new Promise((resolve) => {
    const handler = function () {
      window.removeEventListener('touchstart', handler);
      resolve();
    };
    window.addEventListener('touchstart', handler);
  });
  return Promise.race([p, onTouchPromise]);
};

// 引⽤

delayMS(2000).then(() => {
  console.log(333); // 控制⾮⾸屏dom节点的渲染
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值