前端八股文---常问精简版(Vue)

3,481 阅读5分钟

1. Vue的生命周期(必背)

  1. Vue实例创建会有初始化过程,这个过程中会运行叫做生命周期的钩子函数,方便用户在特定阶段能有机会加入自己的代码。

  2. 总共可以分为八个阶段:创建前后,载入前后,更新前后,销毁前后;创建有beforecreate,created;载入有beforemount,mounted;更新有beforeUpdate,Updated;销毁有beforeDestory,destoryed

  3. 在开发中,

    • beforecreate通常用在插件开发中执行一些初始化任务,比如注入全局变量;
    • created:组件初始化完毕,可以访问各种数据,获取接口数据等;
    • Mounted:获取访问数据和dom元素,访问子组件等;
  4. 此外如果加入keep-alive,被keep-alive缓存的组件还会有激活前beforeActive,和停用时actived

2. Vue的通信方式有几种?隔代组件通信方式用哪种方式解决?

  • Props/$emit 适用父子组件通信
  • Ref与parent/parent/children适用于父子组件通信;
  • attrs/attrs/listeners 适合隔代组件通信;
  • Provide/inject适用于隔代组件的通行;
  • Evenbus(中央事件总线)适用于父子隔代兄弟组件;
  • Vuex适用于隔代组件的通信
  • Slot插槽方式

3.  V-if和V-show的区别?(必背)

  • v-show操作的是DOM元素的display属性,有更高的初始渲染开销;
  • v-if操作的是DOM元素的创建和销毁,有更高的切换开销;
  • 因此,频繁的切换用v-show,切换较少用v-if。

4. 谈谈你对Vuex的理解?(硬背)

  • Vuex是一个专门为Vue.js开发的状态管理模式,vuex的应用核心就是store仓库,Store基本上就是个容器,包含着应用中大部分的state状态;
  • Vuex的状态存储是响应式的,改变store中的状态的唯一途径就是通过commit(提交)mutation,方便跟踪每一个状态的变化;
  • Vuex有几个模块
    • State:定义了应用状态的数据结构,可以在这里设置默认的初始状态;
    • Getter:允许组件从store中获取数据,mapGetters辅助函数仅仅将store中的getter映射到计算属性;
    • Mutation:唯一更改store中状态的方法,且必须是同步函数;
    • Action:用于提交mutation,而不是直接更改状态,包含异步操作;
    • Module:允许将单一的store拆分为多个store且同时保存在单一的状态树。

5.  Vue中组件data为什么必须是函数?(了解)

因为js中只有函数拥有作用域,这样每个组件实例都有自己的作用域,不会相互影响。

6. Vue响应式原理?(全文背诵好吧,我自己总结的,coderwhy视频最后讲的)

  • 首先通过监听器observer对data数据的所有属性进行遍历以及劫持监听,通过object.defineProperty的set方法可以监听数据的改变,通过get方法获取数据的对应的值;接着通过发布者(dep)订阅者(watcher)模式,将每个属性的get方法调用者作为watcher添加进对应的dep的subs数组里,当相应属性发生改动时,在set方法里通过调用dep的notify方法通知所有watcher调用updata方法进行页面数据更新;
  • 此外还有个解析器Compile对页面指令进行解析,将相关指令初始化成一个watcher,并替换模板数据和绑定相应的函数,以上就是响应式原理。

7. 说说Router(得了解)

  • 路由的安装(搭建路由框架)
    • 导入路由对象,并调用Vue.use ( VueRouter );
    • 创建路由实例,并且传入路由映射配置;
    • 在Vue实例中挂载创建的路由实例。
  • 使用vue-router的步骤
    • 创建路由组件
    • 配置路由映射:组件和路径映射关系
    • 使用路由:通过<router-link><router-view>
  • 可以再组件的映射关系中传参配置history模式,默认是hash模式
  • route存放pathparamsquery参数,route存放path、params、query参数,router提供push、replace、go、back等方法
  • 可以配置动态路由
  • 可以进行路由的懒加载
  • 传递参数的方式主要有params和query
  • 导航守卫:beforeEach,有时我们需要通过路由来进行一些操作,比如最常见的登录权限验证,当用户满足条件时,才让其进入导航,否则就取消跳转,并跳到登录页面让其登录。

8. Vue项目 优化性能方法

  • 给v-for循环项加上key提高diff计算速度
  • 防抖和节流
  • 图片大小优化和图片懒加载v-lazy
  • 第三方库的按需引入
  • 路由懒加载
  • 重复代码放入common.js,并使用mixin混入提取重复代码
  • 使用slot封装重复调用组件
  • 使用计算属性computed,有缓存,性能高

9. 项目中碰到过什么困难?

  • 在MVVM模式下,视图和模型只能通过ViewModel进行交互,他能监听数据的变化,然后通知视图更新,实际上实现了双向绑定;

  • MVC是应用最广的软件架构之一,分为模型,视图,控制;MVC是单向通信;

  • 区别

    • MVC中Controller演变成MVVM的ViewModel
    • MVVM通过数据来显示视图层而不是节点操作
    • MVVM主要解决了MVC中大量的dom才做使页面渲染性能降低,加载速度变慢,影响用户体验的现象。

10. 项目中碰到过什么困难?

  • 经常会碰到一些bug,逻辑上有
    • vuex刷新数据丢失,可以直接存本地或者使用可持续性插件vuex-persistedstate
    • 设置overflow:auto失效,组件嵌套很多,原因找到最外层已经给过overflow了,下级的子组件给了固定高度
    • scroll滚动刷新失效,找到内置的refresh方法,每次调用一下,并且给这方法进行防抖操作
    • 子级添加图标,封装递归方法,循环遍历里面有某字段就继续向深层遍历直到没有后添加一个属性,用于判断是否添加某个class,勾选某个数据,前面图标变色,让后台给我创建一个字段,我用nextTick重新刷新树等
  • 样式上使用element-ui问题还挺多,一般会用chrome调试,
    • 碰到过子元素高度无效,设置flex-shrink:0 不使用伸缩解决

11. nexttick 做什么用的?

  1. 作用:Vue.nextTick用于延迟执行一段代码,它接受2个参数(回调函数和执行回调函数的上下文环境),如果没有提供回调函数,那么将返回promise对象)
  2. 应用场景:在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中
  3. DOM是浏览器创建并保留在内存中的网页的虚拟副本。创建、修改、删除 HTML 元素,这些属于 “DOM 操作”。

12. data的深层的属性改动,刷新用$set

  1. 受 ES5 的限制,Vue.js 不能检测到对象属性的添加或删除。因为 Vue.js 在初始化实例时将属性转为 getter/setter,所以属性必须在 data 对象上才能让 Vue.js 转换它,才能让它是响应的。
  2. this.$set(this.data,”key”,value')
  3. set函数接收三个参数分别为 target、key、val,其中target的值为数组或者对象

13. computed和watch的区别(三个)

  • 功能上:computed是计算属性,watch是监听一个值的变化,然后执行对应的回调。

  • 是否调用缓存:computed中的函数所依赖的属性没有发生变化,那么调用当前的函数的时候会从缓存中读取,而watch在每次监听的值发生变化的时候都会执行回调。

  • 是否调用return:computed中的函数必须要用return返回,watch中的函数不是必须要用return。

  • computed默认第一次加载的时候就开始监听;watch默认第一次加载不做监听,如果需要第一次加载做监听,添加immediate属性,设置为true(immediate:true)

  • 使用场景:computed----当一个属性受多个属性影响的时候,使用computed-----购物车商品结算。watch–当一条数据影响多条数据的时候,使用watch-----搜索框.

15. 数组转字符串,字符串转数组 用法

    1. 数组转化成字符串 array.join('')
    1. 字符串转化数组 string.split()
    1. String() Number()

16. websocket

    1. 解决了即时通讯,本该通过轮询向服务器发送请求,占用带宽且服务器cpu占用高,websocket可以从服务器主动向客户端推送消息的一种网络协议,且消耗少
    1. 通过message事件接收数据,open建立连接回调

17. three.js结合vue做的登录界面

  1. 动态登录页面,有自转的地球,星星和星云
  2. 创建一个场景
  3. 设置光源
  4. 创建相机,设置相机位置和相机镜头的朝向
  5. 创建3D渲染器,使用渲染器把创建的场景渲染出来
  6. 为场景添加背景颜色,或创建一个盒模型(球体、立方体),给盒模型的内部贴上图片,再把相机放在这个盒模型内部以达到模拟场景的效果。
  7. 为场景设置光源的颜色、强度,同时还可以设置光源的类型(环境光、点光源、平行光等)、光源所在的位置
  8. 正交相机:无论物体距离相机距离远或者近,在最终渲染的图片中物体的大小都保持不变。用于渲染2D场景或者UI元素是非常有用的。透视相机:被用来模拟人眼所看到的景象。它是3D场景的渲染中使用得最普遍的投影模式
  9. 用webgl渲染出你精心制作的场景。它会创建一个canvas进行渲染
  10. 场景并没有动效,原因是这次渲染的仅仅只是这一帧的画面。为了让场景中的物体能动起来,我们需要使用requestAnimationFrame,所以我们可以写一个loop函数
  11. 星星的运动效果,实际就是沿着z轴从远处不断朝着相机位置移动,直到移出相机的位置时回到起点,不断重复这个操作;创建自转的地球,和移动的云(平面几何)

18. 登录界面

  1. 验证用户名和密码后,调用登录接口登录成功后,将返回的token存到store中,如果参数中含有redirect,则跳转到该路由
  2. 存储token,定义获取用户信息和权限的action,获取并存储用户信息等数据
  3. 分别配置静态路由和动态路由数据
  4. 导航前置守卫,判断是否为在白名单,如果是则直接跳转next()
  5. 判断是否有token,没有则跳转到login页面
  6. 有token,则判断store中是否有权限菜单列表,如果没有则发起请求获取,对比本地动态路由数据,过滤后得到路由表,再遍历addRoutes添加。

18. 按钮权限

1.用自定义按钮,对后台返回用户信息里的权限信息进行处理来进行展示或者不展示某按钮,Vue.directive("permission"

19. 自定义指令

  • 复制粘贴指令 v-copy

  • 长按指令 v-longpress

  • 输入框防抖指令 v-debounce

  • 禁止表情及特殊字符 v-emoji

  • 图片懒加载 v-LazyLoad

  • 权限校验指令 v-premission

  • 实现页面水印 v-waterMarker

  • 拖拽指令 v-draggable

20. applycallbind三者的区别在于:

  • 三者都可以改变函数的this对象指向
  • 三者第一个参数都是this要指向的对象,如果没有这个参数或参数为undefinednull,则默认指向全局window
  • 三者都可以传参,但是apply是数组,而call是参数列表,且applycall是一次性传入参数,而bind可以分为多次传入
  • bind是返回绑定this之后的函数,applycall 则是立即执行