Vue часто задаваемые вопросы на собеседовании

опрос
Vue часто задаваемые вопросы на собеседовании

Статьи, которые я написал о vue:

vue

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

Экземпляр Vue имеет полный жизненный цикл, то есть ряд процессов от запуска до создания, инициализации данных, компиляции шаблонов, монтирования Dom -> рендеринг, обновление -> рендеринг, выгрузка и т. д. Мы называем это жизненным циклом Vue.

Жизненный цикл описывать
beforeCreate Когда экземпляр компонента создается, прежде чем свойства компонента вступят в силу
created Экземпляр компонента полностью создан и свойства привязаны, но реальный дом еще не сгенерирован, а $el еще недоступен.
beforeMount Вызывается перед началом монтирования: связанная функция рендеринга вызывается в первый раз.
mounted el заменяется вновь созданным vm.$el, а хук вызывается после его монтирования на экземпляре
beforeUpdate Вызывается перед обновлением данных компонента, перед исправлением виртуального DOM.
update После обновления данных компонента
activited Эксклюзивное, компонент вызывается при активации
deadctivated Эксклюзивная функция Keep-alive, вызываемая при уничтожении компонента.
beforeDestory Вызывается перед уничтожением компонента
destoryed Вызывается после уничтожения компонента

виртуальный дом

  • Поскольку операция DOM занимает много времени, а размер объекта DOM очень велик, существует целых 294 DOM-атрибута одного div;
  • Виртуальный DOM использует собственный объект JS для описания узла DOM, поэтому это намного дешевле, чем создание DOM.
  • VNode — это абстрактное описание реального DOM, его основное определение — это не что иное, как несколько ключевых атрибутов, имя тега, данные, дочерние узлы, ключевые значения и т. д. Другие атрибуты используются для расширения гибкости VNode и реализации некоторых специальных функций. из. Поскольку VNode используется только для рендеринга для сопоставления с реальным DOM и не должен содержать методы для управления DOM, он очень легкий и простой.
  • Виртуальный DOM для реального DOM должен пройти следующие процессы: создание VNode, сравнение, исправление

Ссылаться на:виртуальный дом

diff

принцип двусторонней привязки данных v-model

Двусторонняя привязка данных Vue выполняется через数据劫持комбинировать发布订阅模式То есть данные и представление синхронизируются, данные изменяются, представление изменяется, представление изменяется, и соответственно изменяются данные; основной:Object.defineProperty()метод.

v-modelПо сути, синтаксический сахар, v-model внутренне использует разные свойства и выдает разные события для разных элементов ввода.

  • элементы text и textarea используют атрибут value и событие ввода
  • флажок и радио используют проверенный атрибут и событие изменения
  • поле выбора имеет значение как опору и изменение как событие
<input v-model="sth" /><!-- 二者等价 -->
<input :value="sth" @input="sth = $event.target.value" />

Разница между вычислениями и часами

vue-слот

установить внутри компонента插槽Подобно блоку, положение определяется дочерним компонентом, а содержимое определяется родительским компонентом.

Реализовано распределение контента, улучшена степень настройки компонентов и сделаны компоненты более гибкими.

  1. Слот по умолчанию:

нет нуждыnameатрибут, возьмите первый узел элемента в дочернем компоненте в качестве слота по умолчанию.

<!-- 子组件,组件名:child-component -->
<div class="child-page">
    <h1>子页面</h1>
    <slot></slot> <!-- 替换为 <p>hello,world!</p> -->
</div>

<!-- 父组件 -->
<div class="parent-page">
    <child-component>
        <p>hello,world!</p>
    </child-component>
</div>

<!-- 渲染结果 -->
<div class="parent-page">
    <div class="child-page">
        <h1>子页面</h1>
        <p>hello,world!</p>
    </div>
</div>
  1. Именованные слоты:

Используется с несколькими слотами, воспользуйтесь преимуществамиnameИдентифицирует слот.

<!-- 子组件,组件名:child-component -->
<div class="child-page">
    <h1>子页面</h1>
    <slot name="header"></slot>
    <slot></slot>  <!-- 等价于 <slot name="default"></slot> -->
    <slot name="footer"></slot>
</div>

<!-- 父组件 -->
<div class="parent-page">
    <child-component>
        <template v-slot:header>
          <p>头部</p>  
        </template>
        <template v-slot:footer>
          <p>脚部</p>
        </template>
        <p>身体</p>
    </child-component>
</div>

<!-- 渲染结果 -->
<div class="parent-page">
    <div class="child-page">
        <h1>子页面</h1>
        <p>头部</p>
        <p>身体</p>
        <p>脚部</p>
    </div>
</div>
  1. Слоты с ограниченной областью действия:

Дочерние компоненты передают данные родительским компонентам.

<!-- 子组件,组件名:child-component -->
<div class="child-page">
    <h1>子页面</h1>
    <slot name="header" data="data from child-component."></slot>
</div>

<!-- 父组件 -->
<div class="parent-page">
    <child-component>
        <template v-slot:header="slotProps">
          <p>头部: {{ slotProps.data }}</p>
        </template>
    </child-component>
</div>

<!-- 渲染结果 -->
<div class="parent-page">
    <div class="child-page">
        <h1>子页面</h1>
        <p>头部: data from child-component.</p>
    </div>
</div>

Разница между Vue, Angular и React?

Разница между Vue и AngularJS

  • Angular использует разработку TypeScript, а Vue может использовать javascript, можно использовать TypeScript.
  • AngularJS полагается на грязные данные проверки, поэтомуWatcherЧем больше, тем медленнее; Vue.js использует依赖追踪наблюдение и использование异步队列Обновление, все данные запускаются независимо.
  • AngularJSулучшение сообщества, ВьюСтоимость обучения низкая

Разница между Vue и React

  • Компоненты Vue делятся на глобальную регистрацию и локальную регистрацию.В реакции соответствующие компоненты импортируются, а затем ссылаются на них в шаблоне;
  • propsЕго можно динамически изменять, а подкомпоненты обновляются в реальном времени.В React официально рекомендуется, чтобы props были как чистые функции, с согласованным вводом и выводом, и не рекомендуется менять представления через props;
  • Дочерний компонент обычно вызывает опцию props явно, чтобы объявить данные, которые он ожидает получить. В реакции это не обязательно, а в двух других есть механизм проверки реквизита;
  • Каждый экземпляр Vue реализует интерфейс событий для облегчения связи между родительскими и дочерними компонентами.В небольших проектах нет необходимости внедрять механизм управления состоянием, и react должен реализовать его сам;
  • использовать插槽распространять содержимое таким образом, чтобы можно было смешивать содержимое родительского компонента с собственным шаблоном дочернего компонента;
  • больше вкуса指令系统, так что шаблон может реализовать более богатые функции, в то время как React может использовать только синтаксис JSX;
  • Добавлен синтаксический сахар для Vue.computedа такжеwatch, а в React для этого нужно написать набор логики;
  • Идея реакции заключается вall in js, генерирует html через js, поэтому спроектирован jsx, а js используется для работы css, styled-component, jss и т. д. сообщества, а vue — для объединения html, css, js и использования собственных методов обработки, vue имеет однофайловые компоненты, которые могут записывать html, css и js в один файл, а html предоставляет механизм шаблонов для обработки.
  • react делает очень мало, многое остается сделатьСообществоСделай это, ведь многие вещивстроенныйДа, действительно удобно писать, типаreduxизcombineReducerсоответствуетvuexизmodulesНапример, select соответствует геттеру vuex и вычисляемым компонентам vue.Мутация vuex — это исходные данные, которые изменяются напрямую, а редюсер redux возвращает новое состояние, поэтому redux объединяет неизменяемый для оптимизации производительности и vue в этом нет необходимости.
  • React - это общая идея, функциональная, поэтому уважаемаячистый компонент, данные неизменны,Однонаправленный поток данных, конечно, это можно сделать и в двусторонних местах, таких как объединениеredux-form, горизонтальное разделение компонентов обычно осуществляется через компоненты более высокого порядка. А vue — это переменная данных, двусторонняя привязка, декларативное написание, во многих случаях используется горизонтальное разделение компонентов vue.mixin

$routeа также$routerразница

  • $маршрут路由信息对象, включая параметры информации о маршрутизации, такие как путь, параметры, хэш, запрос, полный путь, соответствие и имя.
  • и $ маршрутизатор路由实例Объект включает в себя методы перехода маршрутизации, функции подключения и т. д.

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

  • Уменьшить размер входного файла
  • Локальный кеш статических ресурсов
  • Включить сжатие Gzip
  • Использование SSR, nuxt.js

Оптимизация в проекте vue

этап кодирования

  • Не пишите слишком много выражений в шаблоне
  • попытаться вычестьdataданные в ,dataДанные будут увеличиватьсяgetterа такжеsetter, соберет соответствующиеwatcher
  • v-ifа такжеv-forнельзя использовать вместе
  • При необходимости используйтеv-forИспользуйте делегаты событий при привязке событий к каждому элементу
  • SPAСтраница принимаетkeep-aliveкомпонент кэша
  • Используйте v-show для частого переключения, v-if для нечастого переключения
  • Добавить ключ при циклическом вызове подкомпонентов,keyГарантия уникальности
  • Ленивая загрузка, асинхронные компоненты с использованием маршрутизации
  • Защита от сотрясений, дросселирование
  • Импорт сторонних модулей по запросу
  • Прокрутите длинный список до области просмотра для динамической загрузки
  • Ленивая загрузка изображения

SEO-оптимизация

  • предварительный рендеринг
  • рендеринг на стороне сервераSSR,nuxt.js

Оптимизация упаковки

  • сжатый код
  • Tree Shaking/Scope Hoisting
  • использоватьcdnЗагружать сторонние модули
  • Многопоточная упаковкаhappypack
  • splitChunksИзвлечение общедоступных документов
  • sourceMapоптимизация

Пользовательский опыт

  • Скелетонный экран
  • PWAВ прогрессивных веб-приложениях используются различные методы для улучшения функциональности веб-приложения, что позволяет веб-приложению представить опыт, аналогичный родному приложению.

Вы также можете использовать оптимизацию кеша (кэш на стороне клиента, кеш на стороне сервера), открытие на стороне сервераgzipкомпрессия и др.

Vue реагирует на данные, зачем вам diff?

Основная причина:粒度

  • Reactпройти черезsetStateЯ знаю, что есть изменение, но я не знаю, где оно изменилось, поэтому мне нужно пройтиdiffУзнайте, что изменилось, и обновите файл dom.
  • VueУже можно узнать, где произошли изменения через реактивные системы, но все изменения через реактивные могут создать много проблем.Watcher, который чрезвычайно требователен к производительности, поэтому Vue использует способ узнать, какой компонент изменился через реагирующую систему, а затем использовать его внутри компонента.diff. Такойсредняя степень детализацииСтратегия, то есть, не генерирует большое количество Наблюдателей, но также уменьшает количество дифф-узлов, убивая двух зайцев одним выстрелом.

Компиляция шаблона Vue

Ядром компиляции является компиляция шаблона шаблона в функцию рендеринга, которая в основном делится на следующие три шага:

  • Сгенерировать AST-дерево
  • оптимизация
  • codegen

Для получения подробной информации см.:Компиляция шаблона шаблона Vue

MVVM

MVVMдаModel-View-ViewModelСокращенное название,MVCсерединаControllerэволюционировать вViewModel.ModelСлои представляют модель данных,ViewПредставляет компоненты пользовательского интерфейса, ViewModel — это уровень представления и модели.мост, данные будут привязаны к слою viewModel и автоматически отобразят данные на странице.При изменении представления слой viewModel будет уведомлен об обновлении данных.

Принцип адаптивных данных (Vue2.x и Vue3.0)

Vue2.xПри инициализации данных используйтеObject.definePropertyпереопределитьdataВсе объекты в依赖收集(собрать наблюдатель текущего компонента), если свойство изменится, соответствующие зависимости будут уведомлены派发更细(модель публикации-подписки).

vue3.0использоватьes6серединаproxyзаменятьObject.definePropertyЗаймитесь мониторингом данных.

Для получения подробной информации см.:Углубленный принцип отклика vue

Сравнение плюсов и минусов Proxy и Object.defineProperty?

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

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

Преимущества объекта. Действительностьследующим образом:

  • Хорошая совместимость, поддержка IE9

вью$nextTick

в следующий разDOMОтложенный обратный вызов выполняется после завершения цикла обновления.nextTickВ основном используются макрозадачи и микрозадачи. В зависимости от среды выполнения попробуйте принять

  • Promise
  • MutationObserver
  • setImmediate
  • Если ничего из вышеперечисленного не работает, используйте setTimeout

Определен асинхронный метод, и вызов NextTick несколько раз будет хранить метод в очереди и очистить текущую очередь через этот асинхронный метод.

Почему данные в компонентах vue должны быть функцией

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

Как компоненты взаимодействуют в vue

  1. Отец к сыну:props
  2. Сын к отцу:$emit,ref
  3. родной брат:EventBus

vue-router

vue-routerЭто официальный подключаемый модуль vue, в основном используемый для управления интерфейсной маршрутизацией. Для прогрессивных интерфейсных сред разработки, таких как Vue, для созданияSPA (одностраничное приложение), необходимо внедрить фронтальную систему маршрутизации, в чем смысл существования Vue-Router. Ядром внешней маршрутизации является:Изменить вид без запроса к бэкенду.

Функции:

  • Измените URL-адрес, не позволяя браузеру сделать запрос к серверу.
  • Обнаружение изменений URL
  • Запись статуса текущей страницы
  • Вы можете использовать функции браузера вперед и назад
  • URL-адрес определяет способ отображения страницы.

Разница между историей и режимом хеширования

1. Принцип реализации

Как режим хеширования, так и режим истории относятся к собственным характеристикам браузера, Vue-Router просто использует эти две характеристики (вызывая интерфейс, предоставленный браузером) для реализации внешней маршрутизации.

2. Сравнительная таблица

разница \ режим hash history
прослушать событие hashChange popstate
недостаток # выглядит некрасиво Обновление подмаршрута 404, ie9 и ниже несовместимо
push-операция window.location.assign window.history.pushState
заменить операцию window.location.replace window.history.replaceState
операция доступа window.history.go window.history.go
обратная операция window.history.go(-1) window.history.go(-1)
форвардная операция window.history.go(1) window.history.go(1)

3. Ограничения на маршрутизацию прослушивателя событий popstateОперации back(), forward() и go() объекта history будут активно запускать событие popstate, но pushState и replaceState не вызовут событие popstate. В настоящее время нам нужно вручную инициировать переход на страницу (рендеринг). .

4. Решение по обновлению подмаршрута

historyОбновление подмаршрута режима вызовет ошибку 404, поэтому серверная часть должна сотрудничать, и по умолчанию будет указан несопоставленный маршрут.htmlдокумент Конкретная ссылка:Подробное объяснение режима истории vue-router

5. Обработка совместимости браузера (окружения)

в режиме историиpushState,replaceStateдаHTML5новые функции вIE9будет принудительно понижен для использованияhashрежиме среда без браузера преобразуется вabstract модель.

6. router-link router-linkЩелчок эквивалентен звонку$router.pushметод измененияurl

<router-link>чем написано до смерти<a href="...">будет лучше по следующим причинам:

  1. Будь то режим истории HTML5 или режим хеширования, его поведение одинаково, поэтому, когда вы хотите переключить режим маршрутизации или перейти на использование режима хеширования в IE9, вам не нужно вносить никаких изменений.
  2. В режиме истории HTML5 маршрутизатор-ссылка защищает события кликов, чтобы браузер не перезагружал страницу.
  3. Когда вы используете базовый параметр в режиме истории HTML5, все атрибуты не нужно записывать (базовый путь).

Vue-маршрутизатор маршрутизация ленивая загрузка

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

Существует три способа ленивой загрузки vue-маршрутизации:

  1. vue асинхронный компонент
  2. Импорт ES6()
  3. Требование WebPack. Tensure ()

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

export default new Router({
  routes: [
    {
      path: '/home',',
      component: (resolve) => require(['@/components/home'], resolve),
    },
    {
      path: '/about',',
      component: (resolve) => require(['@/components/about'], resolve),
    },
  ],
})

2. Импорт ES6()Vue-router предоставляет метод на официальном сайте, который можно понимать как механизм разрешения через Promise. Потому что Promise, возвращаемый функцией Promise, сам является компонентом разрешения, и мы можем использовать import для импорта компонента.

export default new Router({
  routes: [
    {
      path: '/home',
      component: () => import('@/components/home'),
    },
    {
      path: '/about',
      component: () => import('@/components/home'),
    },
  ],
})

1. require.ensure() веб-пакетаВ этом режиме js можно упаковать отдельно по webpackChunkName в параметре.

export default new Router({
  routes: [
    {
      path: '/home',
      component: (resolve) => require.ensure([], () => resolve(require('@/components/home')), 'home'),
    },
    {
      path: '/about',
      component: (resolve) => require.ensure([], () => resolve(require('@/components/about')), 'about'),
    },
  ],
})