需要多看几次的vue知识点(简单+中等)

简单

1. 怎样理解 Vue 的单向数据流

数据总是从父组件传到子组件,子组件没有权利修改父组件传过来的数据,只能请求父组件对原始数据进行修改。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。

中等

2. Vue2.0 响应式数据的原理

整体思路是数据劫持+观察者模式.

  • 使用 Object.defineProperty 将属性进行劫持(只会劫持已经存在的属性),数组则是通过重写数组方法来实现。当页面使用对应属性时,每个属性都拥有自己的 dep 属性,存放他所依赖的 watcher(依赖收集),当属性变化后会通知自己对应的 watcher 去更新(派发更新).

3. Vue 如何检测数组变化

  • 数组考虑性能原因没有用 defineProperty 对数组的每一项进行拦截,而是选择对 7 种数组(push,shift,pop,splice,unshift,sort,reverse)方法进行重写(AOP 切片思想)
  • 所以在 Vue 中修改数组的索引和长度是无法监控到的。需要通过以上 7 种变异方法修改数组才会触发数组对应的 watcher 进行更新.

4. Vue 的父子组件生命周期钩子函数执行顺序

  • 加载渲染过程

父 beforeCreate->父 created->父 beforeMount->子 beforeCreate->子 created->子 beforeMount->子 mounted->父 mounted

  • 子组件更新过程

父 beforeUpdate->子 beforeUpdate->子 updated->父 updated

  • 父组件更新过程

父 beforeUpdate->父 updated

  • 销毁过程

父 beforeDestroy->子 beforeDestroy->子 destroyed->父 destroyed

5. v-model 原理

v-model 只是语法糖而已。

v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:

  • text 和 textarea 元素使用 value property 和 input 事件;
  • checkbox 和 radio 使用 checked property 和 change 事件;
  • select 字段将 value 作为 prop 并将 change 作为事件。

6. Vue 事件绑定原理

  • 原生事件绑定是通过 addEventListener 绑定给真实元素的,组件事件绑定是通过 Vue 自定义的$on 实现的。如果要在组件上使用原生事件,需要加.native 修饰符,这样就相当于在父组件中把子组件当做普通 html 标签,然后加上原生事件。
  • $on$emit 是基于发布订阅模式的,维护一个事件中心,$on 的时候将事件按名称存在事件中心里,称之为订阅者,然后 $emit 将对应的事件进行发布,去执行事件中心里的对应的监听器。

7. vue-router 路由钩子函数是什么 执行顺序是什么

vue 路由守卫分为三种:

  • 一种是全局的路由守卫,通常在实例化路由之后设置,来做一些通用的路由操作,它所有的路由跳转都会执行的操作;
  • 一种是单个路由独享的守卫,在单个路由定义的时候进行设置,所有跳转这个路由都会执行;
  • 另外一种就是组件内的守卫,只在组件内生效.

全局路由守卫类型:

  • router.beforeEach(to, from, next)
  • router.beforeResolve((to, from, next))—在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,被调用.
  • router.afterEach(to, from)

路由独享的守卫:

  • beforeEnter(to, from, next)

组件独享的守卫:

  • beforeRouteEnter(to, from, next)
  • beforeRouteUpdate(to, from, next) —— 动态参数路径改变时,组件实例被复用的时候调用。
  • beforeRouteLeave(to, from, next) —— 导航离开组件所在路由时被调用。

完整的导航解析流程:

  1. 导航被触发。
  2. 在失活的组件里调用 beforeRouteLeave 守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  5. 在路由配置里调用 beforeEnter
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter
  8. 调用全局的 beforeResolve 守卫 (2.5+)。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

8. vue-router 动态路由是什么 有什么问题

我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果:

const User = {
  template: "<div>User</div>",
};
const router = new VueRouter({
  routes: [
    // 动态路径参数 以冒号开头
    { path: "/user/:id", component: User },
  ],
});
复制代码

问题:vue-router 组件复用导致路由参数失效怎么办?

解决方法:

1.通过 watch 监听路由参数再发请求

watch: { //通过watch来监听路由变化
 "$route": function(){
     this.getData(this.$route.params.xxx); //获取用户数据的调用
  }
}
复制代码

2.用 :key 来阻止“复用”

<router-view :key="$route.fullPath" />
复制代码

9. Vuex 为什么要分模块并且加命名空间

模块:由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。

命名空间: 默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名.意思就是拥有自己的一块命名空间,避免每个模块都注册在全局命名空间中,即使每个模块的数据名及方法名都是一样的,也能分清楚,同时也符合更高的复用性和封装性

10. 你都做过哪些 Vue 的性能优化

  • 对象层级不要过深,否则性能就会差
  • 不需要响应式的数据不要放到 data 中(可以用 Object.freeze() 冻结数据)
  • v-if 和 v-show 区分使用场景
  • computed 和 watch 区分使用场景
  • v-for 遍历必须加 key,key 最好是 id 值,且避免同时使用 v-if
  • 大数据列表和表格性能优化-虚拟列表/虚拟表格
  • 防止内部泄漏,组件销毁后把全局变量和事件销毁
  • 图片懒加载
  • 路由懒加载
  • 第三方插件的按需引入
  • 适当采用 keep-alive 缓存组件
  • 防抖、节流运用
  • 服务端渲染 SSR or 预渲染
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享