Резюме вопросов интервью Vue, которые вам нужно знать

Vue.js

краткое изложение вопросов интервью vue

1. Разница между vue и реагированием

  • => То же самое:

    1. 数据驱动页面,提供响应式的试图组件
    2. 都有virtual DOM,组件化的开发,通过props参数进行父子之间组件传递数据,都实现了webComponents规范
    3. 数据流动单向,都支持服务器的渲染SSR
    4. 都有支持native的方法,react有React native, vue有wexx
    
  • => Разница:

     1.数据绑定:Vue实现了双向的数据绑定,react数据流动是单向的
     2.数据渲染:大规模的数据渲染,react更快
     3.使用场景:React配合Redux架构适合大规模多人协作复杂项目,Vue适合小快的项目
     4.开发风格:react推荐做法jsx + inline style把html和css都写在js了
     	    vue是采用webpack + vue-loader单文件组件格式,html, js, css同一个文件
    

2. Внедрить MVVM (двусторонняя привязка данных)

  • M: модель modelData
  • V: просмотр интерфейса
  • MV: В качестве моста, отвечающего за передачу представления и модели.

  • Заботьтесь только о потоке данных и уменьшите сильную связь. Самое главное — двусторонняя привязка данных

     关键步骤:
     1.实现数据监听器Observer,用object.defineProperty()重写数据的get/set。
     值更新就在set中通知订阅者更新数据
     2.实现模板编译compile,深度遍历dom树,对每个元素节点的指令模板替换数据以及订阅数据
     3.实现watch用于连接Observer和compile,能够订阅并接受每一个属性的变动的通知,
     执行指令绑定的相应的回调函数,从而更新数据
     4.实现一个订阅器 Dep:订阅器采用 发布-订阅 设计模式,
     用来收集订阅者 Watcher,对监听器 Observer 和 订阅者 Watcher 进行统一管理。
    

  • Между mvc и mvvm нет большой разницы. Это все дизайнерская идея. Главное, что Controller в mvc превратился в viewModel в mvvm. mvvm в основном решает проблему, заключающуюся в том, что большое количество DOM-операций в mvc снижает производительность рендеринга страницы,

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

3. Функция жизненного цикла

    new Vue(创建一个Vue对象)--> beforeCreate --> observer Data(开始监控data对象数据变化) -->
    init event(vue内部初始化事件)

	 --> created()  --> compile(编译模板,把data里面的数据和模板生成html)  -->  
	 beforeMount(还没有生成HTML到元素上)  -->
	
	 mounted(挂载完成,也就是模板中的html渲染到了html页面中)  -->  beforeUpdate (Vritual Dom)  -->
	 updated  --> beforeDestroy --> destroyed	
  • 1. Ajax-запросы лучше размещать в created, страница может обращаться к этому
  • 2. Операция дом должна быть помещена в смонтированный, и дом не был сгенерирован до смонтированного
  • 3. Делайте что-то каждый раз, когда вы входите/выходите из компонента, какую функцию ловушки использовать:
    • Без кэширования: вы можете использовать созданные и смонтированные хуки при входе, а также beforedDestory (вы можете получить к нему доступ) и уничтожить при выходе
    • Кэш: после кэширования компонента функции beforeCreate, created, beforeMount, смонтированные не будут запускаться при первом входе в компонент. Если вы хотите что-то делать каждый раз, когда входите в компонент, вы можете поместить его в хук, который активирует кешированный компонент.

4. Расскажите мне о своем понимании одностраничного SPA, каковы его преимущества и недостатки?

  • SPA (одностраничное приложение) загружает соответствующие HTML, JavaScript и CSS только при инициализации веб-страницы. После загрузки страницы SPA не будет перезагружать или переходить страницу из-за действий пользователя; вместо этого используется механизм маршрутизации для реализации преобразования содержимого HTML и взаимодействия между пользовательским интерфейсом и пользователем, чтобы избежать перезагрузки страницы.

  • преимущество:

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

Исходя из вышеизложенного, SPA оказывает относительно небольшое давление на сервер; Обязанности front-end и back-end разделены, структура понятна, front-end отвечает за логику взаимодействия, а back-end — за обработку данных;

  • недостаток:

    • Первоначальная загрузка занимает много времени: чтобы реализовать функцию и эффект отображения одностраничного веб-приложения, необходимо равномерно загружать JavaScript и CSS при загрузке страницы, а некоторые страницы загружаются по требованию;

Управление прямой и обратной маршрутизацией: поскольку одностраничное приложение отображает весь контент на одной странице, функции браузера прямой и обратной маршрутизации использовать нельзя, и для всех переключений страниц необходимо установить управление стеком само по себе; SEO сложнее: поскольку весь контент динамически заменяется и отображается на странице, у него есть естественная слабость в SEO.

5. Как оптимизировать скорость загрузки SPA Vue

    1.减少入口文件体积
    2.静态资源本地缓存
    3.开启Gzip压缩
    4.使用SSR,nuxt.js

6. В чем разница между v-show и v-if?

  • v-if является истинным условным рендерингом, так как он гарантирует, что обработчики событий и дочерние компоненты внутри условного блока будут правильно уничтожены и воссозданы во время переключения; также лениво: если условие ложно при начальном рендеринге, ничего не произойдет — условный блок победит. t начать рендеринг до тех пор, пока условие не станет истинным в первый раз.
  • v-show намного проще — элемент всегда отображается независимо от начального состояния и просто переключается на основе свойства CSS display.
  • Поэтому v-if подходит для сценариев, которые редко меняют условия во время выполнения и не требуют частого переключения условий; v-show подходит для сценариев, требующих очень частого переключения условий.

7. Как понять односторонний поток данных Vue?

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

Кроме того, каждый раз, когда родительский компонент обновляется, все реквизиты в дочернем компоненте будут обновляться до последнего значения. Это означает, что вы не должны изменять свойства внутри дочернего компонента. Если вы это сделаете, Vue выдаст предупреждение в консоли браузера. Когда дочерний компонент хочет изменить, он может отправить пользовательское событие только через $emit.После того, как родительский компонент получит его, он будет изменен родительским компонентом.

Существует два распространенных сценария попытки изменить реквизит:

  • Это свойство используется для передачи начального значения; затем дочерний компонент захочет использовать его в качестве локальных данных свойства. В этом случае лучше определить локальное свойство данных и использовать это свойство в качестве его начального значения:
props: ['initialCounter'],
data: function () {
  return {
    counter: this.initialCounter
  }
}

  • Это свойство передается как необработанное значение и должно быть преобразовано. В этом случае лучше определить вычисляемое свойство, используя значение этой опоры.
props: ['size'],
computed: {
  normalizedSize: function () {
    return this.size.trim().toLowerCase()
  }
}

8. В чем разница между вычисляемыми и наблюдаемыми сценариями и сценариями приложений?

  • вычисленный: это вычисляемое свойство, зависит от других значений свойств, и вычисленное значение кэшируется.Только когда значение свойства, от которого оно зависит, изменяется, вычисленное значение будет пересчитано при следующем получении вычисленного значения;
  • смотреть: больше роли «наблюдения», похожего на обратный вызов мониторинга некоторых данных, всякий раз, когда отслеживаемые данные изменяются, обратный вызов будет выполняться для последующих операций;

Сценарии применения:

Когда нам нужно выполнить числовое вычисление и зависеть от других данных, мы должны использовать вычисленный, потому что мы можем использовать функцию кэширования вычисленного, чтобы избежать повторного вычисления каждый раз, когда мы получаем значение;

Watch следует использовать, когда нам нужно выполнять асинхронные или дорогостоящие операции при изменении данных, использование опции watch позволяет нам выполнять асинхронные операции (доступ к API), ограничивать частоту выполнения операции и ждать, пока мы не получим окончательный результат. установить промежуточное состояние. Это все вещи, которые вычисляемые свойства не могут сделать.

9. Если вы присваиваете значение непосредственно элементу массива, может ли Vue обнаружить изменение?

Из-за ограничений JavaScript Vue не может обнаружить изменения в следующих массивах:

  • Когда вы напрямую устанавливаете элемент массива по индексу, например:vm.items[indexOfItem] = newValue
  • Когда вы изменяете длину массива, например:vm.items.length = newLength

Для решения первой проблемы Vue предоставляет следующие методы действий:

// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// vm.$set,Vue.set的一个别名
vm.$set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)

Для решения второй проблемы Vue предоставляет следующие методы действий:

// Array.prototype.splice
vm.items.splice(newLength)

10. Порядок выполнения функции привязки жизненного цикла родительского и дочернего компонентов Vue?

Порядок выполнения функции обработчика жизненного цикла родительского компонента и дочернего компонента Vue можно разделить на следующие 4 части:

  • Загрузить процесс рендеринга

родитель beforeCreate -> созданный родитель -> родитель beforeMount -> дочерний beforeCreate -> созданный дочерний элемент -> дочерний beforeMount -> смонтированный дочерний элемент -> смонтированный родительский элемент

  • Процесс обновления подкомпонента

родитель до обновления -> дочерний перед обновлением -> дочерний обновлен -> родительский обновлен

  • Процесс обновления родительского компонента

родитель перед обновлением -> родитель обновлен

  • процесс разрушения

родитель перед уничтожением -> дочерний перед уничтожением -> дочерний уничтожен -> родитель уничтожен

11. В каком жизненном цикле вызывается асинхронный запрос?

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

  • Он может быстрее получать данные на стороне сервера и сокращать время загрузки страницы;
  • ssr не поддерживает функции beforeMount и монтируемые хуки, поэтому добавление его в created способствует согласованности;

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

Перед вызовом функции хука Mount Vue уже смонтировал скомпилированный шаблон на странице, поэтому доступ к операции DOM можно получить с помощью Mounted. Конкретную диаграмму жизненного цикла vue можно увидеть ниже.После понимания работы каждого этапа всего жизненного цикла вопросы интервью, связанные с жизненным циклом, не будут для вас сложными.

13. Может ли родительский компонент контролировать жизненный цикл дочернего компонента?

Например, есть родительские компоненты Parent и дочерние компоненты Child, Если родительский компонент прослушивает монтирование дочернего компонента, он будет выполнять некоторую логическую обработку, которая может быть достигнута следующим методом записи:

// Parent.vue
<Child @mounted="doSomething"/>
    
// Child.vue
mounted() {
  this.$emit("mounted");
}

Приведенное выше необходимо вручную инициировать событие родительского компонента через $emit.Более простой способ можно отслеживать через @hook, когда родительский компонент ссылается на дочерний компонент, как показано ниже:

//  Parent.vue
<Child @hook:mounted="doSomething" ></Child>

doSomething() {
   console.log('父组件监听到 mounted 钩子函数 ...');
},
    
//  Child.vue
mounted(){
   console.log('子组件触发 mounted 钩子函数 ...');
},    
    
// 以上输出顺序为:
// 子组件触发 mounted 钩子函数 ...
// 父组件监听到 mounted 钩子函数 ...     

Разумеется, метод @hook может прослушивать не только смонтированные, но и другие события жизненного цикла, такие как создание, обновление и т. д.

14. Почему данные в компоненте должны быть функцией, а затем возвращать объект, тогда как в новом экземпляре Vue данные могут быть напрямую объектом?

// data
data() {
  return {
	message: "子组件",
	childName:this.name
  }
}

// new Vue
new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: {App}
})


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

15. Принцип v-модели?

В основном мы используем инструкцию v-model в проекте vue для создания двусторонней привязки данных к таким элементам, как ввод формы, текстовое поле, выбор и т. д. Мы знаем, что v-model по сути является синтаксическим сахаром, а v-model используется внутри. для разных элементов ввода Различные свойства и генерировать разные события:

  • элементы text и textarea используют атрибут value и событие ввода;
  • флажок и радио используют проверенный атрибут и событие изменения;
  • Поле выбора имеет значение как реквизит и изменение как событие.

В качестве примера возьмем элемент формы ввода:

<input v-model='something'>
    
相当于

<input v-bind:value="something" v-on:input="something = $event.target.value">

Если в пользовательском компоненте v-model по умолчанию будет использовать свойство с именем value и событие с именем input , например:

父组件:
<ModelChild v-model="message"></ModelChild>

子组件:
<div>{{value}}</div>

props:{
    value: String
},
methods: {
  test1(){
     this.$emit('input', '小红')
  },
},

16. Какие существуют способы связи между компонентами Vue?

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

(1)props / $emit Для связи между родительскими и дочерними компонентами Этот метод лежит в основе компонентов Vue, и я полагаю, что большинство студентов слышали о нем, поэтому я не буду его здесь представлять.

(2)ref 与 $parent / $children Для связи между родительскими и дочерними компонентами

  • ref: при использовании в обычном элементе DOM ссылка указывает на элемент DOM; при использовании в дочернем компоненте ссылка указывает на экземпляр компонента.
  • $parent / $children: доступ к родительскому/дочернему экземпляру

(3)EventBus ($emit / $on)Подходит для общения между родителями и детьми, между поколениями, братьями и сестрами Этот метод использует пустой экземпляр Vue в качестве центральной шины событий (центра событий), которая используется для запуска событий и прослушивания событий, тем самым реализуя связь между любыми компонентами, включая родительско-дочерние, межпоколенческие и одноуровневые компоненты.

(4)$attrs/$listeners Для межпоколенческого компонента коммуникации

  • $attrs: содержит привязки свойств (кроме 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 является магазин. «Хранилище» — это, по сути, контейнер, который содержит большую часть состояния вашего приложения.

  • Хранилище состояния Vuex является реактивным. Когда компонент Vue считывает состояние из хранилища, если состояние в хранилище изменяется, соответствующий компонент будет эффективно обновлен соответствующим образом.
  • Единственный способ изменить состояние в хранилище — это явно зафиксировать мутации. Это позволяет нам легко отслеживать каждое изменение состояния.

17. Вы когда-нибудь использовали Vuex?

Vuex — это шаблон управления состоянием, разработанный для приложений Vue.js. Ядром каждого приложения Vuex является магазин. «Хранилище» — это, по сути, контейнер, который содержит большую часть состояния вашего приложения.

(1) Хранилище состояния Vuex является реактивным. Когда компонент Vue считывает состояние из хранилища, если состояние в хранилище изменяется, соответствующий компонент будет эффективно обновлен соответствующим образом.

(2) Единственный способ изменить состояние в хранилище — это явно зафиксировать мутацию. Это позволяет нам легко отслеживать каждое изменение состояния.

В основном он включает в себя следующие модули:

  • Состояние: здесь можно установить структуру данных, которая определяет состояние приложения и начальное состояние по умолчанию.
  • Геттеры: позволяет компонентам получать данные из хранилища, вспомогательная функция mapGetters просто сопоставляет геттеры в хранилище с локальными вычисляемыми свойствами.
  • Мутация: единственный способ изменить состояние в хранилище и должна быть синхронной функцией.
  • Действие: используется для отправки мутаций вместо прямого изменения состояния и может содержать произвольные асинхронные операции.
  • Модуль: позволяет разделить одно хранилище на несколько хранилищ и хранить их в одном дереве состояний одновременно.

18. Вы использовали Vue SSR? Говорите о ССР?

Vue.js — это фреймворк для создания клиентских приложений. По умолчанию компоненты Vue могут выводиться в браузере для создания DOM и управления DOM. Однако также возможно отображать тот же компонент в виде строк HTML на стороне сервера, отправлять их непосредственно в браузер и, наконец, «активировать» эти статические теги как полностью интерактивное приложение на стороне клиента.

То есть: SSR примерно означает, что vue рендерит весь html-фрагмент из тега на стороне клиента на сервере, а сформированный сервером html-фрагмент напрямую возвращается клиенту.Этот процесс называется рендерингом на стороне сервера.

Преимущества и недостатки рендеринга SSR на стороне сервера следующие:

(1) Преимущества рендеринга на стороне сервера:

  • Улучшение SEO: поскольку содержимое страницы SPA получается через Ajax, и сканер поисковой системы не ждет асинхронного завершения Ajax перед обходом содержимого страницы, поэтому в SPA страница, полученная через Ajax, не может быть просканирована. содержание; а SSR напрямую возвращает отображаемую страницу с сервера (данные уже включены в страницу), поэтому сканер поисковой системы может сканировать отображаемую страницу;
  • Более быстрое время поступления контента (более быстрая загрузка на первом экране): SPA будет ждать загрузки всех js-файлов, скомпилированных с помощью Vue, прежде чем начать рендеринг страницы.Это занимает определенное время для загрузки файлов и т. д., поэтому первый экран рендеринг требует определенного времени; SSR напрямую рендерит страницу сервером и возвращает ее для отображения напрямую, не дожидаясь загрузки js-файлов и повторного рендеринга, поэтому SSR имеет более быстрое время поступления контента;

(2) Недостатки рендеринга на стороне сервера:

  • Дополнительные условия разработки: например, рендеринг на стороне сервера поддерживает только две функции-ловушки, beforeCreate и created, из-за чего некоторым внешним библиотекам расширений потребуется специальная обработка, прежде чем они смогут работать в приложениях рендеринга на стороне сервера; и их можно развернуть в любых статических приложениях. Полностью статическое одностраничное приложение SPA на сервере отличается, и приложение для рендеринга на стороне сервера должно находиться в операционной среде сервера Node.js;
  • Большая нагрузка на сервер: рендеринг полного приложения в Node.js, очевидно, требует больше ресурсов ЦП, чем сервер, который просто обслуживает статические файлы (интенсивность ЦП — интенсивный ЦП), поэтому, если вы ожидаете среду с высоким трафиком (высокий трафик), подготовьтесь к соответствующую нагрузку на сервер и разумно используйте стратегию кэширования.

19. Какие режимы маршрутизации есть у vue-router?

vue-router имеет 3 режима маршрутизации: хеш, история, абстракция, Соответствующий исходный код выглядит следующим образом:

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}`)
	}
}

Среди них описания трех режимов маршрутизации следующие:

  • hash: Используйте хеш-значение URL-адреса для маршрутизации. Поддерживает все браузеры, включая браузеры, не поддерживающие HTML5 History Api;

  • history : зависит от HTML5 History API и конфигурации сервера. Дополнительные сведения см. в разделе Режим истории HTML5;

  • abstract : поддерживает все среды выполнения JavaScript, такие как серверная часть Node.js. Маршруты автоматически переводятся в этот режим, если API браузера не найден.

20. Можете ли вы рассказать о принципах реализации режимов маршрутизации по хешу и истории, обычно используемых в vue-router?

(1) Принцип реализации хэш-режима

Ранняя реализация внешней маршрутизации была основана на location.hash. Принцип реализации очень прост: значением location.hash является содержимое после # в URL. Например, для следующего веб-сайта его значение location.hash равно '#search':

https://www.word.com#search

Реализация режима хеш-маршрутизации в основном основана на следующих особенностях:

  • Хэш-значение в URL-адресе — это только состояние клиента, то есть, когда на сервер делается запрос, хэш-часть не отправляется;

Изменения хеш-значения добавят запись в историю доступа браузера. Следовательно, мы можем управлять переключением хэша через кнопки браузера назад и вперед;

  • Вы можете передать тег a и установить атрибут href.Когда пользователь щелкнет этот тег, хеш-значение URL-адреса изменится, или используйте JavaScript, чтобы присвоить значение loaction.hash, чтобы изменить хэш-значение URL-адреса;
  • Мы можем использовать событие hashchange для прослушивания изменений в хеш-значении для перехода (рендеринга) страницы.

(2) Принцип реализации режима истории

HTML5 предоставляет History API для реализации изменений URL. Наиболее важными API являются следующие два: history.pushState() и history.repalceState(). Эти два API могут манипулировать историей браузера без обновления. Единственное отличие состоит в том, что в первом случае добавляется новая запись истории, а во втором — прямая замена текущей записи истории, как показано ниже:

window.history.pushState(null, null, path);
window.history.replaceState(null, null, path);

Реализация режима маршрутизации по истории в основном основана на наличии следующих особенностей:

  • PushState и repalceState — два API для работы и реализации изменений URL-адресов;
  • Мы можем использовать событие popstate для прослушивания изменений в URL-адресе для перехода (рендеринга) страницы;
  • history.pushState() или history.replaceState() не будут вызывать событие popstate, тогда нам нужно вручную вызвать переход на страницу (рендеринг).

21. Как платформа Vue реализует мониторинг объектов и массивов?

Если вас спросят, как Vue реализует двустороннюю привязку данных, все обязательно ответят, что данные перехватываются через Object.defineProperty(), но Object.defineProperty() может перехватывать данные только для свойств, а не всего объекта. hijacked, но, как мы все знаем из фреймворка Vue, Vue может обнаруживать изменения в объектах и ​​массивах (операции некоторых методов), так как же он это реализует? Мы смотрим на соответствующий код следующим образом:

  /**
   * Observe a list of Array items.
   */
  observeArray (items: Array<any>) {
    for (let i = 0, l = items.length; i < l; i++) {
      observe(items[i])  // observe 功能为监测数据的变化
    }
  }

  /**
   * 对属性进行递归遍历
   */
  let childOb = !shallow && observe(val) // observe 功能为监测数据的变化

Глядя на исходный код Vue выше, мы можем знать, что инфраструктура Vue обходит массив и рекурсивно обходит объект, так что Object.defineProperty() также может отслеживать объекты и массивы (операции некоторых методов).

22. Сравнение прокси и Object.defineProperty

Преимущества прокси заключаются в следующем:

  • Прокси может напрямую контролировать объект, а не собственность;
  • Прокси может напрямую отслеживать изменения в массиве;
  • Прокси имеет целых 13 методов перехвата, не ограничиваясь apply, ownKeys, deleteProperty, has и т.д. Object.defineProperty не имеет;
  • Proxy возвращает новый объект, мы можем использовать новый объект только для достижения цели, а Object.defineProperty может только просматривать свойства объекта и изменять их напрямую;

В качестве нового стандарта Proxy будет подвергаться постоянной оптимизации производительности производителями браузеров, что является бонусом производительности легендарного нового стандарта;

Преимущества Object.defineProperty заключаются в следующем:

  • Он имеет хорошую совместимость и поддерживает IE9, но Proxy имеет проблемы совместимости с браузерами и не может быть сглажен полифиллами, поэтому автор Vue заявил, что необходимо дождаться следующей основной версии (3.0), которая будет переписана с помощью Proxy.

23. Как Vue использует vm.$set() для решения проблемы, когда новые добавленные свойства объектов не могут отвечать?

Ограничено современным JavaScript, VueНевозможно обнаружить добавление или удаление свойств объекта. Поскольку Vue выполняет преобразования геттера/сеттера для свойств при инициализации экземпляра, свойство должно существовать в объекте данных, чтобы Vue мог преобразовать его в реактивный. Но Vue предоставляетVue.set (object, propertyName, value) / vm.$set (object, propertyName, value)Чтобы реализовать добавление адаптивных свойств к объектам, как это реализует сам фреймворк?

Давайте посмотрим на соответствующий исходный код Vue:vue/src/core/instance/index.js

export function set (target: Array<any> | Object, key: any, val: any): any {
  // target 为数组  
  if (Array.isArray(target) && isValidArrayIndex(key)) {
    // 修改数组的长度, 避免索引>数组长度导致splcie()执行有误
    target.length = Math.max(target.length, key)
    // 利用数组的splice变异方法触发响应式  
    target.splice(key, 1, val)
    return val
  }
  // key 已经存在,直接修改属性值  
  if (key in target && !(key in Object.prototype)) {
    target[key] = val
    return val
  }
  const ob = (target: any).__ob__
  // target 本身就不是响应式数据, 直接赋值
  if (!ob) {
    target[key] = val
    return val
  }
  // 对属性进行响应式处理
  defineReactive(ob.value, key, val)
  ob.dep.notify()
  return val
}

Из вышеприведенного исходного кода видно, что принцип реализации vm.$set таков:

  • Если целью является массив, непосредственно используйте метод объединения массива, чтобы активировать соответствующую формулу;
  • Если целью является объект, он сначала определит, существует ли свойство и является ли объект отзывчивым.Наконец, если свойство должно быть обработано в ответ, отзывчивая обработка выполняется путем вызова метода defineReactive (метод defineReactive используется, когда Vue инициализирует объект и дает объект. Свойство принимает Object.defineProperty для динамического добавления метода, вызываемого функцией геттера и сеттера)

24. Каковы преимущества и недостатки виртуального DOM?

преимущество:

  • Гарантированный нижний предел производительности: виртуальный DOM фреймворка должен адаптироваться к любым операциям, которые могут быть сгенерированы API верхнего уровня. Реализация некоторых операций DOM должна быть универсальной, поэтому его производительность не оптимальна, но по сравнению с грубой Производительность операции DOM намного лучше, поэтому виртуальный DOM фреймворка может как минимум гарантировать, что вы все еще можете обеспечить хорошую производительность без ручной оптимизации, то есть нижний предел гарантированной производительности;
  • Нет необходимости вручную манипулировать DOM: нам больше не нужно вручную манипулировать DOM, нам нужно только написать логику кода View-Model.Фреймворк свяжет виртуальный DOM и данные в обоих направлениях, чтобы помочь нам обновить представление предсказуемым образом, значительно повышая эффективность нашей разработки;
  • Кроссплатформенность: виртуальный DOM по сути является объектом JavaScript, а DOM тесно связан с платформой.В отличие от этого, виртуальный DOM может выполнять более удобные кроссплатформенные операции, такие как серверный рендеринг, разработка weex и т. д.

недостаток:

  • Невозможно выполнить экстремальную оптимизацию: хотя виртуальный DOM + разумная оптимизация достаточны для удовлетворения требований к производительности большинства приложений, в некоторых приложениях с чрезвычайно высокими требованиями к производительности виртуальный DOM не может быть выбран и оптимизирован.

25. Принцип реализации виртуального DOM?

Принцип реализации виртуального DOM в основном включает следующие три части:

  • Смоделируйте настоящее дерево DOM с помощью объектов JavaScript и абстрагируйте настоящий DOM;

  • алгоритм diff — сравнивает различия двух виртуальных DOM-деревьев;

  • Алгоритм Паха - применяет разницу двух виртуальных объектов DOM к настоящему дереву DOM.

  • Подробная статья о виртуальном DOM

26. v-html связанные

27. Что делает ключ в Vue?

Ключ — это единственная метка для vnode в Vue. С этим ключом наша операция сравнения может быть более точной и быстрой. Процесс сравнения Vue можно обобщить следующим образом: oldCh и newCh имеют по две переменные с головкой и хвостом. oldStartIndex、oldEndIndex 和 newStartIndex、newEndIndex, они будут сравнивать новый узел и старый узел попарно, то есть есть 4 метода сравнения:newStartIndex 和oldStartIndex 、newEndIndex 和 oldEndIndex 、newStartIndex 和 oldEndIndex 、newEndIndex 和 oldStartIndex, если вышеуказанные 4 сравнения не совпадают, если ключ установлен, ключ будет использоваться для повторного сравнения.В процессе сравнения обход будет склоняться к середине.Как только StartIdx > EndIdx указывает, что по крайней мере один из oldCh и newCh был пройден, закончит сравнение.

Таким образом, функция ключа в Vue такова: ключ — это единственная метка для vnode в Vue, с помощью этого ключа наша операция сравнения может быть более точной и быстрой.

Точнее: поскольку ключ не используется повторно на месте, повторного использования на месте можно избежать в той же самой функции Node a.key === сравнение b.key. Так будет точнее.

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

function createKeyToOldIdx (children, beginIdx, endIdx) {
  let i, key
  const map = {}
  for (i = beginIdx; i <= endIdx; ++i) {
    key = children[i].key
    if (isDef(key)) map[key] = i
  }
  return map
}

28. Какие оптимизации вы внесли в свой проект Vue?

Если вы не оптимизировали проект Vue, вы можете обратиться к другой статье.Оптимизация производительности проекта Vue — практическое руководство, статья в основном знакомит с тем, как оптимизировать проект Vue по 3 основным аспектам и 22 второстепенным аспектам.

(1) Оптимизация на уровне кода

  • v-if и v-show различают сценарии использования
  • Вычисляемые и наблюдаемые сценарии использования
  • v-for обход должен добавить ключ к элементу и избегать одновременного использования v-if
  • Оптимизация производительности длинного списка
  • уничтожение событий
  • Отложенная загрузка ресурса изображения
  • Отложенная загрузка маршрута
  • Внедрение сторонних плагинов по запросу
  • Оптимизация производительности бесконечного списка
  • Рендеринг на стороне сервера SSR или предварительный рендеринг

(2) Оптимизация на уровне Webpack

  • Webpack сжимает изображения
  • Сокращение избыточного кода с ES6 до ES5
  • Извлечь общедоступный код
  • Предварительная компиляция шаблона
  • Извлечь CSS компонента
  • Оптимизировать исходную карту
  • Анализ результатов сборки
  • Оптимизация компиляции для проектов Vue

(3) Оптимизация основных веб-технологий

  • Включите сжатие gzip
  • кеш браузера
  • Использование CDN
  • Найдите узкие места в производительности с помощью Chrome Performance

29. Модульный

  • основная концепция:
  1. В js модуль — это файл (js-файл), который реализует определенную функцию

  2. Следуйте механизму модулей, загружайте любой модуль, который хотите

  3. Модульная разработка должна соответствовать спецификациям

  • js реализует модульную спецификацию

          1.AMD 浏览器  requirejs  模块被异步加载,
          模块加载不影响后面语句的运行 默认使用baseURL+ paths的路经解析方式
          2.CommonJS  nodejs  
          3.ES6的import/export
          4.CMD 浏览器端 
    
  • Решенные проблемы: 1. Конфликт имен 2. Зависимость от файлов 3. Повторное использование модулей 4. Единая спецификация и метод разработки

30. Расскажите об идее компонентизации Vue и React

  • 1. Когда мы разрабатываем каждую страницу, будет много повторяющихся функций, таких как xxxx в элементе. Такой чисто нестраничный пользовательский интерфейс стал нашими часто используемыми компонентами пользовательского интерфейса, а первоначальные внешние компоненты относятся только к компонентам пользовательского интерфейса.
  • 2. Поскольку бизнес-логики становится все больше и больше, мы хотим, чтобы наши компоненты обрабатывали множество вещей.Это то, что мы часто называем компонентизацией.Этот компонент не является компонентом пользовательского интерфейса, а бизнес-компонентом, который включает в себя конкретный бизнес.
  • 3. Идея развития - разделяй и властвуй. Эффект снижения сложности разработки и стоимости обслуживания в наибольшей степени. И несколько человек могут сотрудничать, каждый пишет разные компоненты и, наконец, формирует страницу, похожую на строительные блоки.

31. Что вы знаете о грядущих функциях vue3.0?

Готовится к выпуску Vue 3.0. Цель Vue 3.0 — сделать ядро ​​Vue меньше, быстрее и мощнее, поэтому Vue 3.0 добавляет следующие новые функции:

(1) Изменения в механизмах мониторинга

В версии 3.0 появится реализация наблюдателя на основе прокси, обеспечивающая полный языковой охват реактивной трассировки. Это устраняет многие ограничения реализации на основе Object.defineProperty в Vue 2:

  • Может отслеживать только свойства, а не объекты

  • Обнаружение добавления и удаления атрибутов;

  • Обнаружение изменений индекса и длины массива;

  • Поддерживаются Map, Set, WeakMap и WeakSet.

Новый наблюдатель также предоставляет следующие возможности:

  • Публичный API для создания наблюдаемых. Это обеспечивает простое и легкое решение для управления состоянием между компонентами для сценариев малого и среднего масштаба.
  • Ленивое наблюдение используется по умолчанию. В 2.x, независимо от того, насколько велики реактивные данные, они будут наблюдаться при запуске. Если ваш набор данных большой, это может привести к значительным накладным расходам при запуске приложения. В 3.x наблюдайте только за данными, используемыми для рендеринга изначально видимой части приложения.
  • Более точные уведомления об изменениях. В версии 2.x форсирование нового свойства через Vue.set приведет к тому, что наблюдатели, зависящие от этого объекта, будут уведомлены об изменении. В версии 3.x будут уведомлены только наблюдатели, которые зависят от определенных свойств.
  • Неизменяемый наблюдаемый: мы можем создать «неизменяемую» версию значения (даже вложенного свойства), если только система временно не «разблокирует» его внутри. Этот механизм можно использовать для замораживания изменений за пределами доставки свойств или дерева состояний Vuex.
  • Улучшенные функции отладки: мы можем использовать новые хуки renderTracked и renderTriggered, чтобы точно отслеживать, когда и почему компонент перерисовывается.

(2) Шаблон

В шаблоне нет серьезных изменений, меняется только слот области.Механизм 2.x вызывает изменение слота области, и родительский компонент будет повторно визуализирован, в то время как 3.0 изменяет слот области на метод функции, поэтому что только это повлияет на повторный рендеринг дочерних компонентов и улучшит производительность рендеринга.

В то же время, что касается аспекта функции рендеринга, vue3.0 также внесет ряд изменений, чтобы упростить привычку напрямую использовать API для создания vdom.

(3) Объявление компонента объектного стиля

Компоненты в vue2.x передают ряд опций по объявлению, а объединение с TypeScript необходимо выполнять с помощью некоторых декораторов.Хотя это может выполнять функции, это более проблематично. В версии 3.0 метод объявления компонентов был изменен на классоподобный метод записи, что упрощает его комбинирование с TypeScript.

Кроме того, исходный код vue также написан на TypeScript. На самом деле, когда функция кода сложна, должна быть система статического типа для выполнения некоторого вспомогательного управления. Теперь vue3.0 также был полностью переписан с использованием TypeScript, что упрощает объединение TypeScript с открытым API. Статическая система типов действительно необходима для поддержки сложного кода.

(4) Изменения в других аспектах

Изменения vue3.0 являются всеобъемлющими, затрагиваются только основные 3 аспекта, и есть некоторые другие изменения:

  • Поддерживает пользовательские рендереры, так что weex можно расширить с помощью пользовательских рендереров вместо прямого разветвления исходного кода.
  • Поддержка компонентов Fragment (несколько корневых узлов) и Portal (рендеринг содержимого компонентов в других частях dom) и работа с некоторыми особыми сценариями.
  • На основе оптимизации treeshaking предоставляется больше встроенных функций.

32. Знаете ли вы, какой механизм веб-шаблонов используется для синтаксиса шаблонов vue? Расскажите мне о своем понимании этого механизма шаблонов

Vue использует синтаксис Mustache, который представляет собой синтаксис двойных фигурных скобок.

Движок шаблона: Отвечает за сбор данных и представление данных в другой форме или внешнем виде.

преимущество:

  • Ремонтопригодность (легко изменить позже);
  • Масштабируемость (если вы хотите увеличить функцию, удобно увеличить спрос);
  • Повышена эффективность разработки (лучше организована логика программы и удобна отладка);
  • Выглядит удобно (сложно написать неправильно)

32. Знаете ли вы, какой механизм веб-шаблонов используется для синтаксиса шаблонов vue? Расскажите мне о своем понимании этого механизма шаблонов

Vue использует синтаксис Mustache, который представляет собой синтаксис двойных фигурных скобок.

Движок шаблона: Отвечает за сбор данных и представление данных в другой форме или внешнем виде.

преимущество:

  • Ремонтопригодность (легко изменить позже);
  • Масштабируемость (если вы хотите увеличить функцию, удобно увеличить спрос);
  • Повышена эффективность разработки (лучше организована логика программы и удобна отладка);
  • Выглядит удобно (сложно написать неправильно)

33. Как определить глобальный метод для vue?

Первый: смонтируйте его на прототипе Vue. Запишите глобальный метод в файл, а затем смонтируйте цикл for к прототипу Vue.Недостаток в том, что при вызове этого метода нет подсказки.

 Object.keys(tools).forEach(key => {
      Vue.prototype[key] = tools[key]
 })

Второй: используйте миксин global mixin, потому что методы в миксине будут сливаться с каждым созданным однофайловым компонентом. Преимущество этого в том, что при вызове этого метода появляется подсказка.

Vue.mixin(mixin)
new Vue({
    store,
    router,
    render: h => h(App),
}).$mount('#app')



import tools from "./tools"
import filters from "./filters"
import Config from '../config'
import CONSTANT from './const_var'

export default {
    data() {
        return {
            CONFIG: Config,
            CONSTANT: CONSTANT
        }
    },
    methods: {
        // //将tools里面的方法挂载到vue上,以方便调用,直接this.$xxx方法名就可以了
        // Object.keys(tools).forEach(key => {
        //     Vue.prototype[key] = tools[key]
        // })
        //将tools里面的方法用对象展开符混入到mixin上,以方便调用,直接this.$xxx方法名就可以了
        ...tools
    },
    filters: {
        // //将filter里面的方法添加了vue的筛选器上
        // Object.keys(filters).forEach(key => {
        //     Vue.filter(key, filters[key])
        // })
        ...filters
    }
}

34. Что делать, если vue2.0 больше не поддерживает использование фильтров в v-html?

  • определить метод в методе
htmlFilter(htmlString){
return htmlString.replace(/+s/g,'')
}
  • В vue v-html="htmlFilter(htmlString)" может

35. Как решить проблему, когда статические изображения ресурсов становятся недействительными после упаковки vue?

Установить assetsPublicPath Изменить assetsPublicPath: '/' на assetsPublicPath: './'

Последний vue-cli должен создать vue.config.js в корневом каталоге и настроить в нем publicPath.