2020年面试遇到的问题

一、Vue

1. 简单介绍一下Vue的各个生命周期

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

breforeCreate(): 在实例创建前阶段,Vue 实例的挂载元素 el 还没有,这个阶段实例的 data 和 methods 是读不到的。

created():实例创建后,这个阶段已经完成数据观测,属性和方法的运算,watch/event 事件回调,mount 挂载阶段还没有开始。$el 属性目前不可见,数据并没有在DOM元素上进行渲染。

created完成之后,进行template编译等操作,将template编译为render函数,有了render函数后才会执行beforeMount()

beforeMount():在 beforeMount 阶段,Vue 实例的$el 和 data 都初始化了,但还是挂载之前为虚拟的 dom 节点,相关的 render 函数首次被调用。

mounted():Vue 实例挂载完成之后调用,el选项的DOM节点被新创建的 vm.$el 替换,并挂载到实例上去,之后调用此生命周期函数,此时实例的数据在DOM节点上进行渲染。

后续的钩子函数执行的过程都是需要外部的触发才会执行

更新前/后:有数据的变化,会调用beforeUpdate,然后经过Virtual Dom,最后updated更新完毕。

销毁前/后:当组件被销毁的时候,会调用beforeDestory,以及destoryed。在执行 destroy 方法后,对 data 的改变不会再触发周期函数,说明此时 Vue 实例已经解除了事件监听以及和 dom 的绑定,但是 dom 结构依然存在。

2. computed和watch的区别

computed:
计算属性是用来声明式的描述一个值依赖了其它的值。当你在模板里把数据绑定到一个计算属性上时,Vue 会在其依赖的任何值导致该计算属性改变时更新 DOM。这个功能非常强大,它可以让你的代码更加声明式、数据驱动并且易于维护。

特点及注意:①有缓存机制;②不能接受参数;③可以依赖其他computed,甚至是其他组件的data;④不能与data中的属性重复

watch:监听的是你定义的变量,当你定义的变量的值发生变化时,调用对应的方法。

①可接受两个参数(当前值和旧值);②监听时可触发一个回调,并做一些事情;③监听的属性必须是存在的;④允许异步

watch配置:handler(回调函数)、deep(是否监听对象内部值的变化,监听数组的变动不需要这么做。)、immediate (是否立即执行)

总结:

当有一些数据需要随着另外一些数据变化时,建议使用computed;

当有一个通用的响应数据变化的时候,要执行一些业务逻辑或异步操作的时候建议使用watch;

3. $router和$route的区别

$route 为’路由信息对象’,是一个跳转的路由对象,每一个路由都会有一个route对象,是一个局部的对象,包括path,params,hash,query,fullPath,matched,name等路由信息参数。

$router 为’路由实例’对象,包括了路由的跳转方法,钩子函数等。

4. Vue双向数据绑定的原理

vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty()来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

具体步骤:
第一步:需要 observe 的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter 和 getter 这样的话,给这个对象的某个值赋值,就会触发 setter,那么就能监听到数据的变化;

第二步:compile 解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图;

第三步:Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁,主要做的事情是:

在自身实例化时往属性订阅器(dep)里面添加自己,自身必须有一个 update()方法,待属性变动 dep.notice()通知时,能调用自身的 update() 方法,并触发 Compile 中绑定的回调,则功成身退。

第四步:MVVM 作为数据绑定的入口,整合 Observer、Compile 和 Watcher 三者,通过 Observer 来监听自己的 model 数据变化,通过 Compile 来解析编译模板指令,最终利用 Watcher 搭起 Observer 和 Compile 之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据 model 变更的双向绑定效果。

5. Vue如何优化首页的加载速度?

① 第三方js库按CDN引入;(一、cdn引入; 二、去掉第三方库引入的import; 三、把第三方库的js文件从打包文件里去掉;)

② vue-router路由懒加载;

③ 压缩图片资源;

④ 静态文件本地缓存;

http缓存:推荐网站:http缓存浅谈

service worker离线缓存:,缺点:需要在HTTPS站点下,推荐网站:网站渐进式增强体验(PWA)改造:Service Worker 应用详解

6. Vue中 vm.$set的用法

vm.$set( target, propertyName/index, value )
这是全局 Vue.set 的别名。

向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性。

7. Vuex 是什么? 有哪几种属性?

Vuex 是一个专为 vue.js 应用程序开发的状态管理模式。
有 5 种,分别是 state、getter、mutation、action、module

vuex 的 store 是什么?
vuex 就是一个仓库,仓库里放了很多对象。其中 state 就是数据源存放地,对应于一般 vue 对象里面的 data, state 里面存放的数据是响应式的,vue 组件从 store 读取数据,若是 store 中的数据发生改变,依赖它的相应数据的组件也会发生更新,它通过 mapState 把全局的 state 和 getters 映射到当前组件的 computed 计算属性。

vuex 的 getter 是什么?
getter 可以对 state 进行计算操作,它就是 store 的计算属性虽然在组件内也可以做计算属性,但是 getters 可以在多给件之间复用如果一个状态只在一个组件内使用,是可以不用 getters。

vuex 的 mutation 是什么?
更改Vuex的store中的状态的唯一方法是提交mutation。

vuex 的 action 是什么?
action 类似于 muation, 不同在于:action 提交的是 mutation,而不是直接变更状态。action 可以包含任意异步操作。

vuex 的 module 是什么?
面对复杂的应用程序,当管理的状态比较多时;我们需要将vuex的store对象分割成模块(modules)。
如果请求来的数据不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入 vuex 的 state 里如果被其他地方复用,请将请求放入 action 里,方便复用,并包装成 promise 返回。

8. Vue怎么实现强制刷新组件?

① v-if

当v-if的值发生变化时,组件都会被重新渲染一遍。因此,利用v-if指令的特性,可以达到强制

<comp v-if="update"></comp>
<button @click="reload()">刷新comp组件</button>
data() {
 return {
   update: true
  }
 },
 methods: {
  reload() {
     // 移除组件
    this.update = false
      // 在组件移除后,重新渲染组件
      // this.$nextTick可实现在DOM 状态更新后,执行传入的方法。
    this.$nextTick(() => {
      this.update = true
    })
  }
 }

② this.$forceUpdate

<button @click="reload()">刷新当前组件</button>
methods: {
  reload() {
    this.$forceUpdate()
  }
}

二、JavaScript

1. 深拷贝与浅拷贝的区别,实现深拷贝的几种方法

深拷贝与浅拷贝的区别,实现深拷贝的几种方法

2. Es6中的…有哪些用法

不定参数
又称为剩余参数,在函数的命名参数前添加三个点(…)就表明这是一个不定参数,该参数是一个数组。

function pick(object, ...keys) {
    let result = Object.create(null);
    
    for(let i=0, len=keys.length; i<len; i++){
        result[keys[i] = object[keys[i]];
    }
    
    return result;
}

展开运算符

let values = [10, 845, 54, 959];
Math.max(...values);    // 959

不定元素

let colors = ['red', 'blue', 'green', 'pink', 'violet'];
//收集元素
let [firstColor, ...resColor] = colors;
console.log(firstColor);  // red 
console.log(resColor);  // ["blue", "green", "pink", "violet"]
//克隆元素
let [...cloneColors] = colors;
console.log(cloneColors);   // ["red", "blue", "green", "pink", "violet"]

3. 检查数据类型的方法

typeof和instanceof
相对准确的是,Object.prototype.toString.call()。

let set = new Set([1,2,3]);
Object.prototype.toString.call(set);    // [object Set]

4. 怎么随机打乱一个数组

<div>原始值: 1,2,3,4,5,6,7,8,9,10</div>
<div class="demo">原始值</div>
let arr = [1,2,3,4,5,6,7,8,9,10];
let demoDom = document.querySelector('.demo');
let unSort = function(arr) {
    let i = arr.length;
        while(i) {
            let j = Math.floor(Math.random() * i--);
            [arr[j], arr[i]] = [arr[i], arr[j]];
        }
    return arr;
}

https://juejin.im/post/5e703857518825493f6d011c

「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!
0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论