Vue常考知识点

459 阅读5分钟

watch 和 computed 和 methods 区别是什么?

methods是方法,computed是计算属性,watch是监听属性

  1. computedmethods:两者最大的区别就是computed有缓存,如果computed所依赖的属性没有发生变化,就不会重新进行计算,而methods每调用一次就会重新计算一次
  2. watchcomputed:两者最大的区别就是computed是计算出一个属性,而watch则可以做一些其他的事情,比如说将一个数据进行上报,让这个数据也能实现双向绑定

Vue 有哪些生命周期钩子函数?分别有什么用?

  1. beforeCreate
  2. created
  3. beforeMount
  4. mounted
  5. beforeUpdate
  6. updated
  7. beforeUnmount
  8. unmounted

(1)生命周期是什么?

Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模版、挂载 Dom -> 渲染、更新 -> 渲染、卸载等一系列过程,称这是 Vue 的生命周期。

(2)各个生命周期的作用

生命周期描述
beforeCreate组件实例被创建之初,组件的属性生效之前
created组件实例已经完全创建,属性也绑定,但真实 dom 还没有生成,$el还不可用
beforeMount在挂载开始之前被调用:相关的 render 函数首次被调用
mountedel 被新创建的 vm.$el替换,并挂载到实例上去之后调用该钩子
beforeUpdate组件数据更新之前调用,发生在虚拟 DOM 打补丁之前
update组件数据更新之后
activitedkeep-alive 专属,组件被激活时调用
deactivatedkeep-alive 专属,组件被销毁时调用
beforeUnmount组件销毁前调用
unmounted组件销毁后调用

(3)生命周期示意图

image.png

Vue 如何实现组件间通信?

1.props/$emit
2.$emit/$on
3.vuex
4.$attrs/$listeners
5.provide/inject
6.$parent/$children与ref

Vue 组件间通信是面试常考的知识点之一。Vue 组件间通信只要指以下 3 类通信:父子组件通信、隔代组件通信、兄弟组件通信,下面分别介绍每种通信方式且会说明此种方法可适用于哪类组件间通信。

(1)props / $emit 适用 父子组件通信

这种方法是 Vue 组件的基础,相信大部分同学耳闻能详,所以此处就不举例展开介绍。

(2)ref 与 $parent / $children 适用 父子组件通信

  • ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例
  • $parent $children:访问父 / 子实例

(3)EventBus ($emit / $on) 适用于 父子、隔代、兄弟组件通信

这种方法通过一个空的 Vue 实例作为中央事件总线(事件中心),用它来触发事件和监听事件,从而实现任何组件间的通信,包括父子、隔代、兄弟组件。

(4)$attrs/$listeners 适用于 隔代组件通信

  • $attrs:包含了父作用域中不被 prop 所识别 (且获取) 的特性绑定 ( class 和 style 除外 )。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 ( class 和 style 除外 ),并且可以通过 v-bind="$attrs" 传入内部组件。通常配合 inheritAttrs 选项一起使用。
  • $listeners:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件

(5)provide / inject 适用于 隔代组件通信

祖先组件中通过 provider 来提供变量,然后在子孙组件中通过 inject 来注入变量。provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。

(6)Vuex 适用于 父子、隔代、兄弟组件通信

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。“store” 基本上就是一个容器,它包含着应用中大部分的状态 ( state )。

  • Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
  • 改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得可以方便地跟踪每一个状态的变化。

Vue 数据响应式怎么做到的?

响应式系统简述:

  • 任何一个Vue Component都有一个与之对应的Watcher实例
  • Vue的data上的属性会被添加getter和setter属性
  • 当Vue Component render函数被执行的时候,data上会被触碰(touch),即被读,getter方法会被调用,此时Vue会去记录此Vue component所依赖的所有data。(这一过程被称为依赖收集)
  • data被改动时(主要是用户操作),即被写,setter方法会被调用,此时Vue会去通知所有依赖于此的data的组件去调用他们的render函数进行更新。

Vue.set 是做什么用的?

由于Vue不能直接检测到对象内部属性的添加或者修改,因此为了能够实现数据的双向绑定,便需要手动调用vue.set或者this.$set

Vuex 你怎么用的?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。“store” 基本上就是一个容器,它包含着应用中大部分的状态 ( state )。

(1)Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。

(2)改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得可以方便地跟踪每一个状态的变化。

主要包括以下几个模块:

  • State:定义了应用状态的数据结构,可以在这里设置默认的初始状态。
  • Getter:允许组件从 Store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性。
  • Mutation:是唯一更改 store 中状态的方法,且必须是同步函数。
  • Action:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作。
  • Module:允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中。

VueRouter 你怎么用的?

vue-routervue.js的路由插件,(常用router-linkrouter-view) VueRouter是一个vue.js官方的路由管理器

VueRouter中有几个核心概念,分别是 History模式 / 导航守卫 / 路由懒加载

  1. History模式:VueRouter默认的是Hash模式Hash模式History模式最直观的区别就是在于URL里面有没有带#,如果有的话就是Hash模式,否则就是History模式,不过History模式需要后端的支持。
  2. 导航守卫:导航守卫就是路由跳转时的一些钩子函数,这些函数可以在路由跳转的时候做一些事情。
  1. 路由懒加载const Foo = () => {import(',./Foo.vue')}

常用的API有:

  1. router-link:跳转到哪
  2. router-view:在哪显示
  1. this.$router.push():实现路由跳转
  2. this.$router.replace():和this.$router.push()很像,唯一不同的是,他不会在history中添加新的记录
  1. this.$router.params():动态路由匹配

重定向:当用户访问/a的时候,跳转到/b

const router = new VueRouter({
	routes:[
    {path:'/a', redirect:'/b'}
  ]
})

别名:假设/a的别名是/b,那么当用户访问/b的时候,URL仍然保持/b,但实际上路由匹配的是/a

const router = new VueRouter({
	routes:[
    {path:'/a', component:A, alias:'/b'}
  ]
})

路由守卫是什么?

简单的说,路由守卫就是路由跳转过程中的一些钩子函数,这些函数可以在路由跳转的时候做一些事情。

路由守卫主要分为三种,一种是全局的,一种是组件内的,一种是单个路由独享的

  1. 全局的:指路由实例上直接操作钩子函数,特点是所有路由配置的组件都会触发
  1. beforeEach在路由跳转前触发
  2. beforeResolvebeforeEach相似,区别就是beforeResolve是在beforeEach和组件内beforeRouteEnter之后,afterEach之前调用
  1. afterEach在路由跳转完成后触发
  1. 组件内:指在组件内执行钩子函数,相当于为配置路由的组件添加了生命周期钩子函数
  1. beforeRouteEnter在路由进入之前被调用,该钩子在beforeEachbeforeEnter之后,beforeResolveafterEach之前被调用,也就是说,他是在beforeCreate之前就会被触发
  2. beforeRouteUpdate在当前路由改变并且该组件被复用的时候调用,可以通过this访问到实例
  1. beforeRouteLeave在导航离开该组件对应路由的时候被调用,可以通过this访问到实例
  1. 路由独享的:指单个路由在配置的时候也可以设置钩子函数
  1. beforeEnterbeforeEach完全相同,如果两者同时设置的话,那么则会在beforeEach后执行

总结:

当点击切换路由的时候,将按照下面的顺序执行钩子函数

  1. beforeRouteLeave
  2. beforeEach
  1. beforeEnter
  2. beforeRouteEnter
  1. beforeResolve
  2. afterEach
  1. beforeCreate
  2. created
  1. beforeMount
  2. mounted
  1. beforeRouteEnter的next回调