前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue面试题-03

Vue面试题-03

作者头像
客怎眠qvq
发布2022-11-01 16:31:31
2.5K0
发布2022-11-01 16:31:31
举报
文章被收录于专栏:某菜鸟の小屋某菜鸟の小屋

前言

马上要秋招了,搜集整理了一些Vue面试题,包括组件、指令、API等相关内容,巩固基础😎秋招冲冲冲!!!本篇包括:

✅keep-alive的理解 ✅nextTick的理解 ✅vue组件之间的通信方式 ✅Vuex的理解及使用场景

keep-alive的理解

Props:

  • include - string | RegExp | Array。只有名称匹配的组件会被缓存。
  • exclude - string | RegExp | Array。任何名称匹配的组件都不会被缓存。
  • max - number | string。最多可以缓存多少组件实例。

用法:

<keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 <transition> 相似,<keep-alive> 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。

当组件在 <keep-alive> 内被切换时,它的 mountedunmounted 生命周期钩子不会被调用,取而代之的是 activateddeactivated。(这会运用在 <keep-alive> 的直接子节点及其所有子孙节点。)

主要用于保留组件状态或避免重新渲染。

代码语言:javascript
复制
<!-- 基本 -->
<keep-alive>
  <component :is="view"></component>
</keep-alive>

<!-- 多个条件判断的子组件 -->
<keep-alive>
  <comp-a v-if="a > 1"></comp-a>
  <comp-b v-else></comp-b>
</keep-alive>

<!-- 和 `<transition>` 一起使用 -->
<transition>
  <keep-alive>
    <component :is="view"></component>
  </keep-alive>
</transition>

注意,<keep-alive> 是用在其一个直属的子组件被切换的情形。如果你在其中有 v-for 则不会工作。如果有上述的多个条件性的子元素,<keep-alive> 要求同时只有一个子元素被渲染。

includeexclude

includeexclude prop 允许组件有条件地缓存。二者都可以用逗号分隔字符串、正则表达式或一个数组来表示:

代码语言:javascript
复制
<!-- 逗号分隔字符串 -->
<keep-alive include="a,b">
  <component :is="view"></component>
</keep-alive>

<!-- regex (使用 `v-bind`) -->
<keep-alive :include="/a|b/">
  <component :is="view"></component>
</keep-alive>

<!-- Array (使用 `v-bind`) -->
<keep-alive :include="['a', 'b']">
  <component :is="view"></component>
</keep-alive>

匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配。

max

最多可以缓存多少组件实例。一旦这个数字达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉。

代码语言:javascript
复制
<keep-alive :max="10">
  <component :is="view"></component>
</keep-alive>

<keep-alive> 不会在函数式组件中正常工作,因为它们没有缓存实例。

搬运文档链接:

动态组件-keep-alive

https://v3.cn.vuejs.org/guide/component-dynamic-async.html#在动态组件上使用-keep-alive

API-keep-alive

https://v3.cn.vuejs.org/api/built-in-components.html#keep-alive

nextTick的理解

nextTick是Vue提供的一个全局API,由于vue的异步更新策略导致我们对数据的修改不会立刻体现在dom变化上,此时如果想要立即获取更新后的dom状态,就需要使用这个方法。

Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。nextTick方法会在队列中加入一个回调函数,确保该函数在前面的dom操作完成后才调用。

如果我们想在修改数据后立即看到dom执行结果,就需要用到nextTick方法。


官方定义如下:

$nextTick

参数:{Function} [callback]

用法: 将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。

示例:

代码语言:javascript
复制
createApp({
  // ...
  methods: {
    // ...
    example() {
      // 修改数据
      this.message = 'changed'
      // DOM 尚未更新
      this.$nextTick(function() {
        // DOM 现在更新了
        // `this` 被绑定到当前实例
        this.doSomethingElse()
      })
    }
  }
})

Vue.nextTick() 是一个直接暴露在单个 Vue 对象上的全局 API。实际上,实例方法 $nextTick() 只是一个方便的 Vue.nextTick() 包裹器,将其回调的 this 上下文自动绑定到当前实例上,以方便使用。


简单了解nextTick实现,它会在callbacks里面加入我们传入的函数,然后用timerFunc异步方式调用它们,首选的异步方式会是Promise。

代码语言:javascript
复制
let pending=false;
let callBacks=[];//存放的是回调函数,存放的第一个回调函数是数据更新的回调函数
//调用this.$nextTick时执行的函数
function nextTick (cb, ctx) {
    var _resolve;
    callbacks.push(function () {
      if (cb) {
        try {
          cb.call(ctx);
        } catch (e) {
          handleError(e, ctx, 'nextTick');
        }
      } else if (_resolve) {
        _resolve(ctx);
      }
    });
    //在数据首次修改时,pending为false,修改后,pending变成true
    if (!pending) {
      pending = true;
      //在这里用到了事件循环
      timerFunc();
    }
    // $flow-disable-line
    if (!cb && typeof Promise !== 'undefined') {
      return new Promise(function (resolve) {
        _resolve = resolve;
      })
    }
}
//定义eventLoop函数
let timeFunc=null;
if (typeof Promise !== 'undefined' && isNative(Promise)) {
    var p = Promise.resolve();
    timerFunc = function () {
      p.then(flushCallbacks);

      if (isIOS) { setTimeout(noop); }
    };
    isUsingMicroTask = true;
  } else if (!isIE && typeof MutationObserver !== 'undefined' && (
    isNative(MutationObserver) ||
    // PhantomJS and iOS 7.x
    MutationObserver.toString() === '[object MutationObserverConstructor]'
  )) {
    var counter = 1;
    var observer = new MutationObserver(flushCallbacks);
    var textNode = document.createTextNode(String(counter));
    observer.observe(textNode, {
      characterData: true
    });
    timerFunc = function () {
      counter = (counter + 1) % 2;
      textNode.data = String(counter);
    };
    isUsingMicroTask = true;
  } else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {
    timerFunc = function () {
      setImmediate(flushCallbacks);
    };
  } else {
    // Fallback to setTimeout.
    timerFunc = function () {
      setTimeout(flushCallbacks, 0);
    };
}
//清空事件队列中的回调函数,第一个回调函数是flushSchedulerQueue ()
function flushCallbacks () {
    pending = false;
    var copies = callbacks.slice(0);
    callbacks.length = 0;
    for (var i = 0; i < copies.length; i++) {
        copies[i]();
    }
}
//flushSchedulerQueue的核心代码,执行数据更新操作
function flushSchedulerQueue () {
    currentFlushTimestamp = getNow();
    flushing = true;
    var watcher, id;
    queue.sort(function (a, b) { return a.id - b.id; });
    for (index = 0; index < queue.length; index++) {
      watcher = queue[index];
      if (watcher.before) {
        //调用beforeUpdate()钩子函数
        watcher.before();
      }
      id = watcher.id;
      has[id] = null;
      //执行更新
      watcher.run();
    }
  }

参考链接:

nextTick实现原理

https://zhuanlan.zhihu.com/p/195531049

实例方法$nextTick

https://v3.cn.vuejs.org/api/instance-methods.html#nexttick

API-nextTick

https://v3.cn.vuejs.org/api/global-api.html#nexttick

vue组件之间的通信方式

  1. 组件通信方式大体有以下8种:
  • props
  • emit/emit/emit/on
  • children/children/children/parent
  • attrs/attrs/attrs/listeners
  • ref
  • $root
  • eventbus
  • vuex
  1. 根据组件之间关系讨论组件通信最为清晰有效
  • 父子组件 props emit/on parent / children ref attrs / listeners
  • 兄弟组件
    • $parent
    • eventbus
    • vuex
  • 跨层级关系
    • provide/inject
    • $root
    • eventbus
    • vuex

搬运链接:

vue中组件之间的通信方式?

https://github.com/57code/vue-interview/blob/master/public/05-communication/README.md

Vuex的理解及使用场景

Vuex 是一个专为 Vue 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。

  1. Vuex 的状态存储是响应式的;当 Vue 组件从 store 中读取状态的时候,

若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新 2. 改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation, 这样使得我们可以方便地跟踪每一个状态的变化 Vuex主要包括以下几个核心模块:

  1. State:定义了应用的状态数据
  2. Getter:在 store 中定义“getter”(可以认为是 store 的计算属性),

就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来, 且只有当它的依赖值发生了改变才会被重新计算 3. Mutation:是唯一更改 store 中状态的方法,且必须是同步函数 4. Action:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作 5. Module:允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中

搬运链接:

Vuex的理解及使用场景

https://juejin.cn/post/7016593221815910408#heading-69

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-07-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • keep-alive的理解
  • nextTick的理解
  • vue组件之间的通信方式
  • Vuex的理解及使用场景
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档