Разберитесь с некоторыми проблемами, возникающими в ходе личного развития, и запишите личное понимание.
=======================Статьи по теме и библиотеки с открытым исходным кодом ===================== ==
серия статей
1.Прочесывание знаний о внешнем интерфейсе - статьи HTML, CSS
2.Сортировка знаний во внешнем интерфейсе — статьи ES5
3.Сортировка знаний во внешнем интерфейсе — статьи по ES6
4.Сортировка знаний переднего плана — статьи VUE
Лично поддерживаемая библиотека компонентов с открытым исходным кодом
1.bin-ui, библиотека компонентов для ПК на основе vue
2.компоненты организации дерева
3.bin-admin , решение для интеграции системы фонового управления на основе bin-ui
4.bin-data — фреймворк для визуализации данных, основанный на bin-ui и echarts.
========================================================
1 Основной принцип Vue
когда ставишь обычныйJavaScript Объект передается экземпляру Vue в качестве параметра данных, Vue просматривает все свойства этого объекта и используетObject.defineProperty Преобразуйте все эти свойства вgetter/setter。Object.definePropertyЭто функция, которую нельзя скрыть в ES5, поэтому Vue не поддерживает браузеры IE8 и более ранних версий.
Документация здесь рекомендует только официальную документацию. Вы можете найти ответы почти на все вопросы, с которыми вы можете столкнуться в документации. В этой части выбрано только несколько общих вопросов для объяснения. Так что вы можете избежать таких проблем.
2 Механизм данных Vue
Однонаправленный поток данных. Как следует из названия, поток данных является однонаправленным. Направление потока данных можно отследить, поток является единичным, а проблему можно отследить быстрее. Недостатком является то, что это не легко написать. Чтобы внести изменения в пользовательский интерфейс, необходимо создать различные действия для поддержания соответствующего состояния.
Двусторонняя привязка данных: данные связаны, а операция изменения данных скрыта внутри фреймворка. Преимущество заключается в том, что в сценариях с большим количеством взаимодействий с формами это упростит большую часть кода, который не имеет ничего общего с бизнесом. Недостаток в том, что изменение локального состояния нельзя отследить, что усложняет отладку при возникновении ошибки.
В частности, мы обычно используем пользовательские компоненты (такие какbin-uiкнопка в<b-button size=’small’ v-waves
:disabled=’false’>我是按钮<b-button>)середина,sizeиdisabledЭто воплощение единого потока данных.Родительский компонент передает параметры компоненту-кнопке, и поток один.Компонент-кнопке нужно толькоpropsПараметры могут отображаться. Двусторонняя привязка данных в основном отражается в компонентах формы, таких как ввод и v-модель, которые являются синтаксическим сахаром для двусторонней привязки данных. Основной поток данных является односторонним, то естьv-modelэквивалентно связыванию:valueи@input=‘’Прослушайте возвращаемое значение и обновите его.
3 Понимание представления Vue на основе данных
особенности вью:
- Связь между частями двусторонняя
- Используйте двустороннюю привязку: изменения во View автоматически отражаются в ViewModel и наоборот
Традиционная разработка никогда не может избежать работы с DOM.Мы всегда думаем об управлении элементом DOM после того, как данные будут возвращены, но накладные расходы на работу с элементом DOM относительно велики, и разделить уровень представления и бизнес-уровень непросто. Поэтому нам нужно изменить наши привычки. Когда мы завершаем сбор данных, нам нужно только обновить текущее значение состояния vue, а остальную часть операции обновления оставить виртуальному дому vue для ее завершения.
4 Что такое виртуальный дом
Для чего нужен виртуальный DOM? Это начинается с самого браузера.
Как мы знаем, в процессе рендеринга веб-страницы браузер, после загрузки HTML-документа, проанализирует документ и построит дерево DOM, а затем объединит его с деревом CSSOM, сгенерированным путем анализа CSS, чтобы произвести кристаллизацию любовь -RenderObject树, а затем визуализировать дерево RenderObject на странице (конечно, в середине может быть некоторая оптимизация, напримерRenderLayerДерево). Все эти процессы существуют в механизме рендеринга. Механизм рендеринга отделен от механизма JavaScript (JavaScriptCore или V8) в браузере. Однако, чтобы облегчить JS манипулирование структурой DOM, механизм рендеринга будет предоставлять некоторые интерфейсы для JavaScript. звонить. Поскольку эти две части отделены друг от друга, связь обходится дорого, поэтому производительность JavaScript, вызывающего интерфейс, предоставляемый DOM, невелика. Различные передовые методы оптимизации производительности также максимально сокращают количество операций DOM.
А что делает виртуальный DOM? Он реализован непосредственно в JavaScriptDOM树(大致上). HTML-структура компонента не генерирует DOM напрямую, а отображает для создания виртуальногоJavaScript DOMструктуру, реализуя diff Алгоритм находит наименьшие изменения и записывает эти изменения в фактический DOM. Этот виртуальный DOM существует в виде структуры JS, производительность вычислений будет лучше, и производительность будет значительно улучшена, поскольку количество реальных операций DOM уменьшено.
Концепция виртуального дома — это всего лишь краткое введение.Синтаксис шаблона шаблона Vue, включая синтаксис jsx,renderфункция, в то время какrenderКонтент, отображаемый в функции, на самом деле虚拟dom, во фронтенд-разработке, разработке библиотек классов и разработке компонентов,renderНаписание функций также является одним из навыков, которыми необходимо овладеть.
5. Понимание жизненного цикла Vue
Экземпляр vue имеет полный жизненный цикл, который относится к процессу экземпляра от создания до уничтожения.
beforeCreate() 在实例创建之间执行,数据未加载状态
created() 在实例创建、数据加载后,能初始化数据,dom渲染之前执行
beforeMount() 虚拟dom已创建完成,在数据渲染前最后一次更改数据
mounted() 页面、数据渲染完成,真实dom挂载完成
beforeUpadate() 重新渲染之前触发
updated() 数据已经更改完成,dom 也重新 render 完成,更改数据会陷入死循环
beforeDestory() 和 destoryed() 前者是销毁前执行(实例仍然完全可用),后者则是销毁后执行
В жизненном цикле vue создание и подключение являются обычными в повседневной разработке.Конкретное приложение, например, мне нужно получить список новостей и некоторые необработанные данные при загрузке страницы.В это время мы можем вызвать метод в созданная функция ловушки для загрузки данных и для привязки, если иногда нам нужно вручную реализовать диаграмму (ечарты), в это время из-за механизма реализации диаграммы нам нужно убедиться, что элемент DOM был отрендерен Когда диаграмму нужно смонтировать к реальному элементу DOM, она должна быть в смонтированной функции, вызывается метод генерации диаграммы.
6 Разница между v-if и v-show
При использовании v-if и значении false страница не будет создана с этим тегом html.
v-show означает, что независимо от значения true или false элемент html будет существовать, но отображение в CSS отображается или скрывается
навыки и умения:
1. При использовании этих двух будут небольшие проблемы, например, когда используется v-if, если в дочернем элементе есть атрибут ответа, связанный с {{}}, например{{current.name}}, то еслиcurrentЕсли он не существует, то он "может" сообщить об ошибке при рендеринге этого элемента. Почему это возможно? Поскольку v-if может быть оценен как ложный, внутренний элемент вообще не будет рендериться, а если v-show используется, будет сообщено об ошибке, потому что независимо от того, истинно это или ложно, внутренний элемент будет отображаться.Если текущий не инициализирован в это время, будет сообщено об ошибке. Поэтому, если мы используем v-show для отображения скрытых элементов, нам нужно убедиться, что значение внутренней привязки было инициализировано.
2. Личная рекомендация, если внутренние элементы не меняются, такие как изображения, некоторое содержимое стилей и т. Д., Включены и скрыты, вы можете использовать v-show для достижения, а с переходом вы можете достичь лучших требований к производительности. Если вам нужен динамический рендеринг, вы можете использовать v-if
3. В некоторых случаях из-за механизма обновления мы можем использовать v-if, чтобы заставить vue перерисовывать элементы, такие как element и bin-ui Генерация таблиц генерируется динамически на основе ширины и высоты конфигурации, что требует мониторинг размера окна.Для вызова интерфейса, предоставленного компонентом, для обновления размера, но есть насильственное решение v-if, например, рендеринг таблицы при всплывающем окне, напрямую = false при закрытии для принудительного элемент, подлежащий очистке, чтобы гарантировать, что каждый элемент обновляется и перерисовывается.
7 Что такое функция NextTick
Функция this.$nextTick(), официальное определение - это отложенный обратный вызов, выполняемый после завершения следующего цикла обновления DOM.Как правило, мы будем использовать $nextTick() после изменения данных, после чего мы сможем получить обновленный элемент DOM после обратного вызова.
Для конкретного использования этой функции позвольте мне привести пример.Вышеупомянутый элемент, включая мою тяжелую таблицу bin-ui, будет предоставлять функцию интерфейса обновления размера для ручного получения компонента таблицы и перерисовки размера, но эта функция иногда вам кодировать правильный размер Это не было реализовано, так почему это? Причина в том, что Vue выполняется асинхронно при обновлении DOM. Пока он обнаруживает изменения данных, Vue открывает очередь и буферизует все изменения данных, которые происходят в одном и том же цикл событий. Если один и тот же наблюдатель запускается несколько раз, он будет помещен в очередь только один раз. Эта дедупликация во время буферизации важна, чтобы избежать ненужных вычислений и манипуляций с DOM. Затем в следующем цикле обработки событий "tick" vue очищает очередь, чтобы параллельно выполнить фактическую (дедублированную) работу.
Например, когда вы устанавливаетеvm.someData = 'new value', компонент не будет повторно отображаться немедленно. Когда очередь сбрасывается, компонент обновляется в следующий «тик» цикла событий. Большую часть времени нам не нужно заботиться об этом процессе, но если вы хотите сделать что-то на основе обновленного состояния DOM, это может быть немного сложно. Хотя Vue.js
Разработчикам обычно рекомендуется мыслить «управляемым данными» и избегать непосредственного контакта с DOM, но иногда нам приходится это делать. Чтобы дождаться, пока Vue завершит обновление DOM после изменения данных, вы можете использовать сразу после изменения данныхVue.nextTick(callback). Таким образом, функция обратного вызова будет вызываться после завершения обновления DOM. Например:
<div id="example">{{message}}</div>
var vm = new Vue({
el: '#example',
data: {
message: '123'
}
})
vm.message = 'new message' // 更改数据
vm.$el.textContent === 'new message' // false
Vue.nextTick(function () {
vm.$el.textContent === 'new message' // true
})
использовать внутри компонентаvm.$nextTick()Метод экземпляра особенно удобен тем, что не требует глобальногоVue, а в функции обратного вызоваthisАвтоматически привязывается к текущему экземпляру Vue:
Vue.component('example', {
template: '<span>{{ message }}</span>',
data: function () {
return {
message: '未更新'
}
},
methods: {
updateMessage: function () {
this.message = '已更新'
console.log(this.$el.textContent) // => '未更新'
this.$nextTick(function () {
console.log(this.$el.textContent) // => '已更新'
})
}
}
})
так как$nextTick()вернутьPromiseобъект, поэтому вы можете использовать новыйES2017 async/awaitСинтаксис делает то же самое:
methods: {
updateMessage: async function () {
this.message = '已更新'
console.log(this.$el.textContent) // => '未更新'
await this.$nextTick()
console.log(this.$el.textContent) // => '已更新'
}
}
Возвращаясь к описанному выше явлению, поскольку обновление dom является асинхронным и добавляется в очередь, аналогичную асинхронной очереди setTimeout, мы не можем быть уверены, хотите ли вы в настоящее время выполнять событие размера таблицы обновления в текущем кадре рендеринга. Следовательно, после того, как мы динамически вычислим ширину/высоту, нам нужно точно получить компонент после обновления элемента dom, нам нужноnextTickПолучите функцию обновления в функции, чтобы вы могли убедиться, что элемент перерисовывается нормально без необходимости использовать v-if для принудительного обновления.
Обратите внимание на использованиеthis.$nextTickэто официальный метод, мы также можем использоватьsetTimeout(func,20)По умолчанию для имитации функции nextTick установлено значение 20 миллисекунд.20 миллисекунд — это эмпирическое значение, но все же рекомендуется использовать функцию nextTick.
8 Роль ключевых значений во Vue
Когда Vue.js использует v-for для обновления отображаемого списка элементов, по умолчанию используется стратегия «повторное использование на месте». Если порядок элементов данных изменен, Vue не будет перемещать элементы DOM в соответствии с порядком элементов данных, а просто будет повторно использовать каждый элемент здесь и убедиться, что он показывает каждый элемент, который был отрисован по определенному индексу. Роль ключа в основном заключается в эффективном обновлении виртуального DOM.
Основное внимание в этой части уделяется динамическим компонентам и v-for.Чтобы идентифицировать уникальный дом, значение ключа обычно принимает уникальное и уникальное значение, такое как id.
Инвариантные переменные, если только различать дом, вырезанный элемент не будет часто обновляться (добавление, удаление и модификация), можно использовать индексный индекс
9 Компонентная связь
1. Родительский компонент взаимодействует с дочерним компонентом: дочерний компонент связывает данные родительского компонента через атрибут props для реализации связи между двумя сторонами.
2. Дочерний компонент взаимодействует с родительским компонентом: событие родительского компонента инициируется в дочернем компоненте через $emit
3. Передача данных между компонентами, не являющимися родительско-дочерними, и компонентами-сестрами.
- Центральная шина событий eventBus let EventBus = new Вью();
- Управление данными Vuex
- 3.3 обеспечить и ввести впрыск (в основном используется для компонентной формы)
Все реквизиты формируют отношения между их родительскими и дочерними реквизитами.Односторонняя привязка нисходящего канала: обновления родительских реквизитов передаются дочерним компонентам, но не наоборот. Это предотвращает случайные изменения родительского состояния из дочерних компонентов, которые могут сделать поток данных вашего приложения непонятным.
Кроме того, каждый раз, когда родительский компонент обновляется, все реквизиты в дочернем компоненте будут обновляться до последнего значения. это значит тыНетСвойство должно быть изменено внутри дочернего компонента. Если вы это сделаете, Vue выдаст предупреждение в консоли браузера.
Компонентная связь в сочетании с разделом 4.2, например<b-button size=’small’ v-waves :disabled=’false’>我是按钮<b-button>некоторые изsize,:disabled обаpropПередача значения, то есть, передача значения из родительского компонента к дочернему компоненту, вот нота, привязка статических данных, аналогичныхsize=’small’ :disabled=’false’Оба относятся к статической привязке, то есть они не будут динамически изменяться в соответствии со значением ответа в данных родительского компонента.Здесь есть регулирование для привязки данных.Если значение данных вырезать в строку из статических данных, это может быть опущено.v-bind:то есть какsize=’small’, иначе все привязки данных должны использоватьv-bind:, как правило, мы его опускаем. Он начинается с двоеточия, за которым следует значение привязки. Это значение также может быть различными типами данных, выражениями или даже возвратами функции, такими как :data=’[1,2,3]’ :data=’list? list : []’ :data=’33’Ждать
Если это логическое значение, то предлагается способ его записи, например, прямо в компоненте.<b-button disabled>我是按钮<b-button>здесьdisabled эквивалентно:disabled=’true’
10 слотов
Вот краткое введение в концепцию слота.При написании компонента он может предоставлять два типа методов передачи значений, реквизиты и слоты.Разница в том, что слот более гибкий и изменчивый, например, кнопка выше.
<b-button size=’small’ v-waves :disabled=’false’>我是按钮<b-button>«Я кнопка» в середине кнопки — это слот, слот позволяет вам вставлять в него все, что вы хотите, например
<b-button><i class=’iconfont close’></i><span>我是按钮</span><b-button>Вы можете вставить любой контент, который хотите настроить, в компонент, текущая предпосылка заключается в том, что компонент предоставляет<slot></slot>слот по умолчанию для
Это похоже на кассетную игровую приставку, в которую вы играли в детстве: вы можете просто вставить любую кассету, на которой хотите играть.
Но это все еще недостаточно мощно, если я хочу, чтобы символ или элемент был там по умолчанию, когда я вставляю контент, вот что вам нужно, чтобы написать содержимое элемента по умолчанию, которое вы хотите, в середине
Как и в случае с компьютерными материнскими платами, разные производители будут предоставлять разные интерфейсные слоты в соответствии с общим стандартом, чтобы облегчить пользователям расширение по требованию, и слоты для компонентов vue также предоставляют этот способ. Иногда у нас также есть несколько слотов, например
<div class="container">
<header>
<!-- 我们希望把页头放这里 -->
</header>
<main>
<!-- 我们希望把主要内容放这里 -->
</main>
<footer>
<!-- 我们希望把页脚放这里 -->
</footer>
</div>
Для таких случаев элемент
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
Выход
При предоставлении контента в именованный слот мы можем использовать директиву v-slot для элемента и указать его имя в качестве аргумента для v-slot:
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
Теперь все в элементе будет передано в соответствующий слот. Все, что не заключено в с v-slot, будет рассматриваться как содержимое слота по умолчанию.
У слотов есть не только слоты по умолчанию и именованные слоты, но и слоты с областью действия. Например, слот, вставленный родителем в подкомпонент, может получить доступ к данным подкомпонента. Это слот с областью действия. Подробнее см. в bin-ui, элемент -ui Использование таблицы в
11 Смешивание в миксинах
Коллеги, использующие vue для реализации привязки данных в новых проектах, могут обнаружить, что под каждым экземпляром vue пишется строка
mixins:[mixin], для чего это?
Миксины предоставляют очень гибкий способ распространения повторно используемой функциональности в компонентах Vue. Объект миксина может содержать произвольные параметры компонента. Когда компонент использует миксин, все параметры миксина будут «смешаны» с собственными параметрами компонента.
mixinСмешивание очень распространено в разработке Vue, и его использование также очень просто.Вам нужно только помнить, что все атрибуты функции открытого метода могут быть помещены в миксины, в основном для повторного использования кода и уменьшения избыточности кода.Например, инкапсуляция открытого запроса, общедоступный свойства подкачки, переходы по общедоступным запросам и т. д.
mixinСтратегию смешивания можно просто понять как следующие пункты
1. Объекты данных, атрибуты в данных, будут объединены рекурсивно, аналогично оператору расширения es6, если миксин существует, данные, определенные компонентом Zeyi, имеют приоритет.
2. Функция хука с тем же именем объединит массив, например, смонтированный, если определены и компонент, и миксин, оба будут выполнены, и пост, определенный в компоненте, будет выполнен. То есть смешанный код будет выполняться первым.
3. Функции с тем же именем будут перезаписаны. Подобно атрибуту в данных, функция в компоненте и функция в миксине будут рекурсивно объединены, и одно и то же имя будет перезаписано.
12 Как vue получает элемент dom?
Ядром эпохи jQuery является получение элементов DOM и выполнение ряда операций, но как получить элементы DOM, если необходимо получить элементы DOM (например, получить элементы для рисования диаграмм, рисования холста), когда данные Vue управляют представлением .
Vue предоставляет метод, сначала напишите в элементе domref=’table’, Это на самом деле похоже на настройку идентификатора или класса, просто для идентификации и использования Vue.
Способ его получения тоже очень прост, нужно всего лишьthis.$refs.tableилиthis.$refs[‘table’]чтобы получить элемент dom
Если вы установите ref на компонент vue и используетеthis.$refsТо, что получается, является экземпляром этого компонента, и вы можете вызывать внутренние методы компонента через этот экземпляр, такие как метод обновления таблицы, упомянутый выше.
которыйthis.$refs.table.handleResize()
13 Почему vue не запускает адаптивные обновления
Обычно есть две причины этой проблемы.
1.Добавить/удалить без установки свойств адаптивного объекта
Ограничено современным JavaScript (иObject.observeтакже устарело), Vue. Поскольку Vue выполняет преобразование геттера/сеттера для свойств при инициализации экземпляра, свойства должны быть вdataобъект, чтобы Vue преобразовал его в реактивный. Например:
var vm = new Vue({
data:{
a:1
}
})
// `vm.a` 是响应式的
vm.b = 2
// `vm.b` 是非响应式的
Для созданных экземпляров VUE не позволяет динамически добавлять свойства ответа корневого уровня. Однако вы можете использоватьVue.set(object,
propertyName, value)метод для добавления реактивных свойств к вложенным объектам. Например, для:
Vue.set(vm.someObject, 'b', 2)
Вы также можете использоватьvm.$setметоды экземпляра, которые также являются глобальнымиVue.setПсевдоним метода:
this.$set(this.someObject,'b',2)
Иногда вам может понадобиться назначить несколько новых свойств существующему объекту, например, используяObject.assign()или_.extend(). Однако новые свойства, добавленные к объекту таким образом, не будут инициировать обновление. В этом случае вы должны создать новый объект со свойствами исходного объекта и объекта, с которым нужно смешать.
// 代替 `Object.assign(this.someObject, { a: 1, b: 2 })`
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
Анализ: Это проблема копирования объекта, упомянутая выше.Если вы используете только содержимое комментариев для расширения объекта, здесь a и b фактически эквивалентны прямой записи.this.someObject.a=1 ,
this.someObject.b=2, здесь обновление по-прежнему не запускается.
Если это закодировано следующим образом, это по существу эквивалентно созданию нового объекта и изменению адреса ссылки всего отвечающего объекта someObject. Так что перезапустите обновление.
2.Значение индекса массива задает изменение длины элемента или массива
Изменить длину массива или установить элемент
var vm = new Vue({
data(){
return{
list:[{id:1,name:’张三’},{id:2,name:’李四’}]
}
}
})
this.list[1]= {id:3,name:’王五’}
this.list.length = 1
实际输出的效果就是数据变化了但不会更新视图变化
Есть два решения проблемы массива
- Создайте новый массив, чтобы заменить исходные значения массива в целом.
- Использование функции манипулирования массивом в Js (по сути, возвращение нового массива) также является принципом замены массива. Поддерживаемые методы: push, pop, shift, unshift, splice, sort, reverse. Неподдерживаемые методы: filter, concat, slice
Поэтому, когда мы снова сталкиваемся с операциями с массивами, обычно рекомендуется создать новый массив для работы и обновления представления.Вот упомянутая выше глубокая копия. Потому что мы не можем гарантировать, содержит ли массив, с которым мы сейчас работаем, объекты или другие ссылочные типы.
Наконец, в сочетании с вышеупомянутым точным типом суждения реализуется функция глубокого копирования рекурсивного вызова.
function typeOf (obj) {
const toString = Object.prototype.toString
const map = {
'[object Boolean]': 'boolean',
'[object Number]': 'number',
'[object String]': 'string',
'[object Function]': 'function',
'[object Array]': 'array',
'[object Date]': 'date',
'[object RegExp]': 'regExp',
'[object Undefined]': 'undefined',
'[object Null]': 'null',
'[object Object]': 'object'
}
return map[toString.call(obj)]
}
// 深拷贝函数
function deepCopy (data) {
const t = typeOf(data)
let o
if (t === 'array') {
o = []
} else if (t === 'object') {
o = {}
} else {
return data
}
if (t === 'array') {
for (let i = 0; i < data.length; i++) {
o.push(deepCopy(data[i]))
}
} else if (t === 'object') {
for (let i in data) {
o[i] = deepCopy(data[i])
}
}
return o
}