2020年5月面试纪要

前言

今天面了一家国企,具体哪家公司就不提了😂。本人17年毕业,但是16年底就在目前的公司一直工作,面试环节可以说是薄弱的可怜😪。面试官直指痛点,技术可以,但是表述不清楚。面试嘛,大部分都是聊着造火箭的技术,到公司之后拧螺丝。但是没办法,这是现实。因此我努力回忆起了一些今天面试的内容,整理一下用作记录,接下来步入正题。

  • 注意

本文偏重理论和原理,没有过多的代码和图解,读起来可能有些枯燥,刚开始写博客,多多批评!😝

面试主要内容:

  1. SPA应用性能优化
  2. 插槽的使用
  3. 子父组件生命周期的加载顺序
  4. historyhash区别以及原理
  5. ES6的map使用
  6. 聊一下ES5和ES6继承
  7. 兄弟组件如何传值
  8. vuex如果实现状态管理,详细描述一下实现过程

暂时只能回想起这么多,看到这里你是否和我一样觉得这些都是我们日常用到的,但是深究其底层原理,又觉得好像只能说点皮毛。没关系,下面是我整理的资料,希望对各位面试的时候有用!

面试题目解析

前端性能优化

减小代码体积 首先是开发时,我们主要对自己代码的执行有认知,怎么写,才能做到代码量最小并且执行的更快。

  • v-ifv-showv-if是惰性的,只有条件为真的时候才会渲染,v-show是只要执行到此处,就会渲染元素,区分场景 computedwatchcomputed依赖其他数据进行数值计算,避免每次获取值时重新计算;watch是对数据的监听,对数据操作过多时,允许执行异步操作,限制操作频率,设置中间态。

  • v-for遍历,务必为item 添加key,方便 Vue.js 内部机制精准找到该条列表数据。当 state 更新时,新的状态值和旧的状态值对比,较快地定位到 diff ;且v-forv-if优先级高,尽量在v-for中使用v-if以为可能只修改一个值,就需要遍历整个数据表,严重影响速度

  • 图片资源懒加载,使用 vue-lazyload

  • 路由懒加载,避免首页首页长时间白屏,开发路由时使用 import('./***.vue')

  • 第三方插件的按需引入,使用 babel-plugin-component

其次就是 webpack 为我们提供的方法,我们尽管使用即可

  • 对图片进行压缩,使用 image-webpack-loader

  • 提取公共代码,Webpack 内置了专门用于提取多个Chunk 中的公共部分的插件 CommonsChunkPlugin

  • 优化 SourceMap,具体看vue文档吧

web基础优化

  • 服务端开启gzip压缩
  • 对静态资源进行浏览器缓存
  • 利用CDN从服务器上下载 CSS、js 和图片等文件时

插槽

插槽就是Vue实现的一套内容分发的API,将<slot></slot>元素作为承载分发内容的出口。

  • 普通插槽,当子组件绝大部分内容是固定的,只有局部内容变化,这时候可用插槽来实现
  • 具名插槽,有时一个组件中部分内容固定的,但是其他部分分好几个模块变化,这时候可用具名,插槽在slot中添加name来为这个组件来添加多个插槽
  • 作用域插槽,正常来讲父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。但是我们又希望在插槽中获取子组件中的数据,这时为了实现在父级的插槽内容中可用,我们可以将子组件的数据作为 <slot> 元素的一个 attribute 绑定上去。绑定在<slot> 元素上的 attribute 被称为插槽 prop

子父组件生命周期的加载顺序

  • 父组件beforeCreated
  • 父组件created
  • 父组件beforeMounted
  • 子组件beforeCreated
  • 子组件created
  • 子组件beforeMounted
  • 子组件mounted
  • 父组件mounted

注意: 父组件的mounted是在最后执行的。 因此在子组件的 mounted 中渲染父组件在 mounted 阶段请求的数据,是会无反应的。因为子组件 mounted 渲染数据会发生在父组件 mounted 请求数据之前。

history 和 hash 区别以及原理

  • hash,即地址栏 URL 中的 #。比如这个 URL:http://www.abc.com/#/hellohash 的值为 #/hello。它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。
  • history,利用了 HTML5 History Interface 中新增的 pushState()replaceState() 方法。(需要特定浏览器支持)这两个方法应用于浏览器的历史记录栈,在当前已有的 backforwardgo 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。

因此可以说,hash 模式和 history 模式都属于浏览器自身的特性,Vue-Router 只是利用了这两个特性(通过调用浏览器提供的接口)来实现前端路由。

两者对比 1. pushState() 的URL可以是当前URL同源的任意URL;而 hash 只可修改#后面的部分,因此只能设置与当前 URL 同文档的 URL 2. 在浏览器的URL入栈时,pushState()可以是相同的URL,hash 必须和当前的不一样才行 3. 在用URL传参时,pushState()通过 stateObject 参数可以添加任意类型的数据到记录中;而 hash 只可添加短字符串

history 模式下,需要运维对页面路由进行处理,否则切换白屏

ES6的Map

MapSet 都是ES6新增的数据结构,Map类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。 也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应;set类似于数组,但是成员的值都是唯一的,没有重复的值。WeakSet 结构与 Set 类似,也是不重复的值的集合。 但是,它与 Set 有两个区别。首先,WeakSet 的成员只能是对象,而不能是其他类型的值;其次,WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。

聊一下ES5和ES6继承

ES6 中有类 class 的概念,类 class 的继承是通过 extends 来实现的,ES5 中是通过设置构造函数的 prototype 属性,来实现继承的。 ES5继承,构造函数、原型和实例的关系:每一个构造函数都有一个原型对象,每一个原型对象都有一个指向构造函数的指针,而每一个实例都包含一个指向原型对象的内部指针。 ES6继承,class继承,class之间使用extends关键字。子类必须要再 constructor 方法中调用super 方法,否则新建实例会报错,这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工,如果不调用super方法,子类就得不到this对象,注意super关键字指代父类的实例,即父类的this对象。

组件间如何传值

  • 父传子,props
  • 子传父,$emit,或者双向绑定的v-model
  • 非父子组件传值,可以采用发布订阅模式,这种模式在 Vue 中被称为总线机制,或者叫做Bus / 发布订阅模式 / 观察者模式。具体实现如下:
  1. 首先在Vueprotptype(原型)上挂载了一个名字叫做bus的属性,
Vue.prototype.bus = new Vue()
  1. 这个属性指向一个Vue的实例,只要以后调用new Vue()或者创建组件的时候每一个组件上都会有一个bus属性.
// 组件内发送事件:
childclick() {
  this.bus.$emit('change', this.content); //content:要发送的数据
}
  1. 其他组件接收事件
receive(){
  this.bus.$on('change', function(msg) {
    console.log(msg); //获取子组件发送的数据
  });
}

vuex如果实现状态管理,详细描述一下实现过程

vuex的核心api: install函数:用来注册插件到vue里(说白了就是在vue中执行这个函数,并把vue当作参数传入此函数,使用vue的方法和绑定store到各个组件上) store类:state、getters、mutations、actions、modules、plugins 辅助函数:mapState、mapActions、mapMutations

  • Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。(也就是所谓的MVVM)
  • 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutations
  • 如果是异步的,就派发(dispatch)actions,其本质还是提交mutations
  • 怎样去触发actions呢?可以用组件Vue Components使用dispatch或者后端接口去触发
  • 提交mutations后,可以动态的渲染组件Vue Components Vuex 理解了这张图,就理解了vuex的原理
  1. state state是存储的单一状态,是存储的基本数据。
  2. Getters gettersstore的计算属性,对state的加工,是派生出来的数据。就像computed计算属性一样,getter返回的值会根据它的依赖被缓存起来,且只有当它的依赖值发生改变才会被重新计算。
  3. Mutations mutations提交更改数据,使用store.commit方法更改state存储的状态。(mutations同步函数)
  4. Actions actions像一个装饰器,提交mutation,而不是直接变更状态。(actions可以包含任何异步操作)
  5. Module Module是store分割的模块,每个模块拥有自己的state、getters、mutations、actions

请我喝杯咖啡吧 ヾ(^▽^*)))
一介码农ZH - 支付宝 支付宝
一介码农ZH - 微信 微信
共享知识
  • 文章标题: 2020年5月面试纪要
  • 本文作者: 一介码农ZH
  • 本文链接: /post/2020-05-12/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!