«Узнайте из исходного кода» ответы на вопросы Vue, которые интервьюеры не знают

Vue.js
«Узнайте из исходного кода» ответы на вопросы Vue, которые интервьюеры не знают

предисловие

Отвечая на вопросы о Vue, заданные интервьюером, помимо ответа на сценарий, мы можем показать вам небольшой объем исходного кода, чтобы продемонстрировать ваше глубокое понимание Vue.

Эта статья будет последовательно обновляться, и на этот раз она охватывает следующие вопросы:

  1. «Что делает новый Vue()?»
  2. «На каком этапе можно получить доступ к DOM?»
  3. «Расскажите о своем понимании жизненного цикла Vue».
  4. Расширение: что такое новый хук жизненного цикла serverPrefetch?
  5. «Каковы режимы маршрутизации vue-router?»
  6. «Расскажи мне, что ты знаешь о сохранении жизни?»
  7. "Понимание нового глобального API Vue2.6+: Vue.observable()?"

1."new Vue()Что вы наделали? "

newКлючевое слово представляет создание экземпляра объекта, иVueНа самом деле это класс, исходное местоположение/src/core/instance/index.js.

function Vue (options) {
  if (process.env.NODE_ENV !== 'production' &&
    !(this instanceof Vue)
  ) {
    warn('Vue is a constructor and should be called with the `new` keyword')
  }
  this._init(options)
}

Затем мы прыгаем и следим заthis._init(),Прямо сейчасVue.prototype._init,родыsrc\core\instance\init.jsсуществует_init()Внутри метода есть рядinit*Методы

Vue.prototype._init = function (options?: Object) {
    const vm: Component = this
    // ...忽略,从第45行看起
    if (process.env.NODE_ENV !== 'production') {
      initProxy(vm)
    } else {
      vm._renderProxy = vm
    }
    // expose real self
    vm._self = vm
    initLifecycle(vm)
    initEvents(vm)
    initRender(vm)
    callHook(vm, 'beforeCreate')
    initInjections(vm) // resolve injections before data/props
    initState(vm)
    initProvide(vm) // resolve provide after data/props
    callHook(vm, 'created')
    // ...忽略
    if (vm.$options.el) {
      vm.$mount(vm.$options.el)
    }
  }
}

1.1 Здесь мы снова обрисовываем это:

  1. initProxy, прокси области, перехватывающий данные от других компонентов внутри компонента.
  2. initLifecycle, установите связь между родительскими и дочерними компонентами и добавьте к текущему экземпляру некоторые свойства и идентификаторы жизненного цикла. Такие как:$children,$refs,_isMountedЖдать.
  3. initEvents, используется для хранения@hook:生命周期钩子名称="绑定的函数"объект мероприятия. Такие как:$on,$emitЖдать.
  4. initRender, для инициализации$slots,$attrs,$listeners
  5. initInjections, инициализацияinject, обычно используется для более глубокого взаимодействия компонентов, эквивалентно расширенной версииprops. Больше для разработки библиотеки компонентов.

Пока предоставление объявлено на верхнем уровне, следующий уровень может получить доступ к предоставленным данным через инъекцию, независимо от того, насколько она глубока. Это также имеет очевидные недостатки: к нему можно получить доступ на любом уровне, что затрудняет отслеживание данных, и неизвестно, какой уровень объявляет этот или какой уровень или несколько уровней используются.

  • initState, представляет собой сводку инициализации многих опций, в том числе:props、methods、data、computed 和 watchЖдать.
  • initProvide, инициализацияprovide.
  • vm.$mount, смонтируйте экземпляр.

2. "На каком этапе можно получить доступ к DOM?"

Этот ответ можно найти вbeforeCreateтак же какcreatedГоворя о времени вызова, мы упростим код на основе приведенного выше обзора:

callHook(vm, 'beforeCreate')
// 初始化 inject
// 初始化 props、methods、data、computed 和 watch
// 初始化 provide
callHook(vm, 'created')
// 挂载实例 vm.$mount(vm.$options.el)

Итак, когда интервьюер спрашивает вас:

  • beforeCreateтак же какcreatedПри звонке какие данные можно использовать или нет?
  • На каком этапе можно получить доступ к DOM?
  • ЗачемcreatedСмонтировать экземпляр позже?

Знай, как на него ответить.

3. «Расскажите о своем понимании жизненного цикла Vue»

Общий ответ здесь упоминаться не будет, давайте немного углубимся:

  1. created/mounted/updated/destroyed, и соответствующийbeforeкрюк. Они создаются => монтируются => обновляются => уничтожаются.
  2. VueИсходный код определяетmergeHookфункция для перебора константного массиваLIFECYCLE_HOOKS, который на самом деле представляет собой массив строк с тем же именем, что и хук жизненного цикла.
// v2.6.10 最新版
var LIFECYCLE_HOOKS = [
    'beforeCreate',
    'created',
    'beforeMount',
    'mounted',
    'beforeUpdate',
    'updated',
    'beforeDestroy',
    'destroyed',
    'activated',
    'deactivated',
    'errorCaptured',
    // v2.6+ 
    'serverPrefetch'
];

Таким образом, вы можете ответитьactivated & deactivated(активация/деактивация компонента поддержки активности), errorCaptured (хук в версии 2.5 и выше, используемый для обработки ошибок).

3.1 Новые крючки жизненного цикла:serverPrefetchчто это такое?

можно увидеть,serverPrefetchраньшеssrPrefetch. Как следует из названия, это для обработки ssr. Позволяет нам «ждать» асинхронных данных во время рендеринга. Может использоваться в любом компоненте, а не только в компонентах маршрутизации.

Здесь мы размещаем официальный пример:

<!-- Item.vue -->
<template>
  <div v-if="item">{{ item.title }}</div>
  <div v-else>...</div>
</template>

<script>
export default {
  computed: {
    item () {
      return this.$store.state.items[this.$route.params.id]
    }
  },
  serverPrefetch () {
    return this.fetchItem()
  },
  mounted () {
    if (!this.item) {
      this.fetchItem()
    }
  },
  methods: {
    fetchItem () {
      // return the Promise from the action
      return this.$store.dispatch('fetchItem', this.$route.params.id)
    }
  }
}
</script>
  • Подавляющее большинство интервьюеров не будут обращать внимание на записи кода и изменения после версии 2.6+.. вот если ты это скажешьv2.6.10Сдача, тск-тск... интервьюер определенно оценит вас больше.

3.2 Стратегия слияния для крючков жизненного цикла

братьcallHook(vm, 'created')Кстати говоря, сначала определите, есть ли соответствующий названию хук жизненного цикла в опциях компонента, а потом определите, есть лиparentVal(vm). если существуетparentVal(vm)и имеют соответствующие крючки жизненного цикла, какconcatкак массив (parentVal.concat(childVal)). Таким образом, хуки жизненного цикла могут быть записаны в виде массивов. Такие как:

created: [
function () {
  console.log('first')
},
function () {
  console.log('second')
},
function () {
  console.log('third')
}]

Функция ловушки будет выполняться по порядку.

4. «Сколько режимов маршрутизации есть в Vue-router?»

три"hash" | "history" | "abstract", средний человек знает только два"hash" | "history".

Вот исходный код:

switch (mode) {
  case 'history':
    this.history = new HTML5History(this, options.base)
    break
  case 'hash':
    this.history = new HashHistory(this, options.base, this.fallback)
    break
  case 'abstract':
    this.history = new AbstractHistory(this, options.base)
    break
  default:
    if (process.env.NODE_ENV !== 'production') {
      assert(false, `invalid mode: ${mode}`)
    }
}

# mode

Типы:string

По умолчанию:"hash" (浏览器环境) | "abstract" (Node.js 环境)

Дополнительные значения:"hash" | "history" | "abstract"Настройте режим маршрутизации:

  • hash: использоватьURL hashзначение для маршрутизации. Поддерживаются все браузеры, включая неподдерживаемыеHTML5 History Apiбраузер.
  • history: зависит отHTML5 HistoryAPI и конфигурация сервера. ПроверитьHTML5 Historyмодель.
  • abstract: поддерживать всехJavaScriptоперационная среда, напримерNode.jsСервис-Терминал. Если вы обнаружите, что нет браузераAPI, маршрутизатор автоматически перейдет в этот режим.

5. «Расскажите о своемkeep-aliveпонимание? "

Сначала опубликуйте общий ответ:

keep-alive — это компонент, встроенный в Vue, который позволяет содержащимся компонентам сохранять состояние или избегать повторного рендеринга. После vue 2.1.0 в keep-alive добавлены два новых атрибута: include (включенные компоненты кэшируются) и exclude (исключенные компоненты не кэшируются и имеют более высокий приоритет, чем включаемые).

Затем вы можете начать розыгрыш:

  1. <keep-alive>даVueГлобальный абстрактный компонент, реализованный в исходном коде посредством настройки.renderфункций и использовать слоты для кэширования и обновления данных. это определено вsrc/core/components/keep-alive.jsсередина:
export default {
  name: 'keep-alive',
  abstract: true,
  ...
}
  1. Все абстрактные компоненты определяютсяabstractвозможность объявить. Абстрактные компоненты не отображаются реальнымиDOM, и не появляется на пути отношения родитель-потомок (initLifecycleАбстрактные компоненты игнорируются), соответствующие фрагменты кода:
if (parent && !options.abstract) {
  // abstract 即 `ptions.abstract`
  // while 循环查找第一个非抽象的父组件
  while (parent.$options.abstract && parent.$parent) {
    parent = parent.$parent
  }
  parent.$children.push(vm)
}

6. «ПонятьVue2.6+новый глобальныйAPI:Vue.observable()? "

Vue2.6+ новый глобальный APIVue.observable(), как он используется:

import vue from vue;
const state = Vue.observable ({
   counter: 0,
});
export default {
   render () {
     return (
       <div>
         {state.counter}
           <button v-on:click={() => {state.counter ++; }}>
           Increment counter
         </ button>
       </ div>
     );
   },
};

в то время как он определен в/src/core/global-api/index.jsСтрока 48:

import { observe } from 'core/observer/index'
// ...
// 2.6 explicit observable API
Vue.observable = <T>(obj: T): T => {
observe(obj)
return obj
}

посмотри еще разimportизobserve, последний коммит был в12/1/2018,Хорошо. . . .

Суть в том, чтобы раскрытьobserve(obj)После просмотра данных код не изменился. понятно?

Спросите рекомендацию инсайдера в Шэньчжэне

В настоящее время я готовлюсь к смене работы и надеюсь, что вы и дамы из отдела кадров сможете предложить надежную работу в Шэньчжэне!

  • WeChat:huab119
  • Почта:454274033@qq.com

Сборник статей автора Nuggets

Нет публики: