открытие
Библиотека компонентов может помочь нам сократить усилия по разработке. Нам не нужно делать все с нуля. Соединяя вместе небольшие компоненты, мы получаем конечную страницу, которую хотим. В повседневной разработке, если нет конкретных бизнес-требований, использование библиотеки компонентов для разработки, несомненно, является более удобным и эффективным решением, а качество относительно выше.
В настоящее время существует много библиотек компонентов с открытым исходным кодом.Есть много отличных библиотек компонентов как для систем React, так и для Vue.Например, я часто использую elementui и iview. Конечно, есть еще какие-то библиотеки компонентов, и суть их как раз в том, чтобы сохранить процесс повторения колеса построения базовых компонентов. У некоторых компаний могут быть особые потребности в собственных продуктах, и они не хотят использовать стиль библиотек компонентов с открытым исходным кодом, или у них есть некоторые внутренние бизнес-проекты, которые необходимо использовать, но компоненты, которые не могут быть удовлетворены проектами с открытым исходным кодом, нуждаются В то время самостоятельное создание набора библиотек компонентов стало проектом, необходимым в качестве бизнес-драйвера.
В этой статье будут объяснены два этапа «подготовки» и «практики», а также шаг за шагом завершено создание библиотеки компонентов. Общее содержание следующее:
- Подготовить: В основном мы говорим о некоторых базовых знаниях, прежде чем создавать библиотеку компонентов, чтобы проложить путь к практическому этапу.
- упражняться: С некоторыми основными понятиями мы будем использовать практический случай для создания базовой библиотеки. Доставьте дизайн библиотеки компонентов из процесса выполнения.
Я надеюсь, что благодаря распространению этой статьи и включению простогоПрактический случай, который позволяет вам сделать такой маленький шаг от роли пользователя библиотеки компонентов к роли создателя библиотеки компонентов.Когда вы используете библиотеку компонентов ежедневно, у вас есть итог в вашем сердце, и тогда моя цель было достигнуто.
Адрес нашего кейса:arronkler.github.io/lime-ui/
Соответствующее репо:GitHub.com/Arron KL и/к...
Подготовка: Что вы должны знать, прежде чем построить компонентную библиотеку?
В этой главе в основном мы хотим сначала проанализировать и прояснить некоторые концепции, которые обычно используются при создании библиотек компонентов, которым редко уделяется внимание в бизнес-концепциях. Я объясню это в двух аспектах: проектирование и компоненты, и расскажу о некоторых известных мне хитростях и ловушках, чтобы помочь нам подготовиться к реальному процессу.
Проекты. Какие дополнительные соображения следует учитывать при выполнении проекта библиотеки компонентов?
При выполнении проектов библиотек компонентов и обычных бизнес-проектов должны быть некоторые вещи, которые не очень нужны нашим бизнес-проектам, но проекты библиотек классов обычно учитывают некоторые вещи. библиотеки Дополнительные вещи, которые следует учитывать.
тестирование компонентов
Многие разработчики обычно спешат на бизнес-проекты, а потом не пишут много тестовых скриптов в общих бизнес-проектах. Но в процессе создания проекта библиотеки компонентов лучше иметь соответствующий тестовый скрипт компонента. Есть как минимум два преимущества:
- Автоматически тестируйте функциональность компонентов, которые вы пишете
- Измените код, не беспокоясь о том, что это повлияет на предыдущих пользователей. (Тестовый скрипт сообщит вам, есть ли непредвиденные эффекты)
Я думаю, что для проектов библиотек классов второе преимущество по-прежнему очень важно, чтобы гарантировать, что вы не повлияете на тех, кто уже использует созданную вами библиотеку классов в процессе непрерывного обновления и итерации проекта. однажды и сделать его проект большой проблемой, то вы не можете гарантировать, что другие потеряют работу. (Как и в предыдущем событии «Рождественская снежинка» antd)
Поскольку мы собираемся написать библиотеку компонентов vue, рекомендуемый набор инструментов для тестирования здесь:vue-test-utilsэтот инструмент,vue-test-utils.vuejs.org/zh/. Различные тестовые функции и методы, представленные в нем, вполне могут удовлетворить наши потребности в тестировании. Для конкретной установки и использования, пожалуйста, обратитесь к его документации.
Что мы в основном хотим упомянуть здесь, так это то, чтоЧто именно измеряет тестирование компонентов?
Мы дали здесь очень интуитивную картинку, когда вы видите эту картинку, вы также должны знать ответ на этот вопрос.
Это фото из видеоWoohoo.YouTube.com/watch?V=o IP…, также очень хорошая речь, рекомендованная vue-test-util.Если вы хотите узнать больше, вы можете зайти и посмотреть.
Итак, оглядываясь назад, тестирование компонентов на самом деле требует, чтобы мы тестировали функциональные характеристики компонентов не только с точки зрения создателей. С точки зрения пользователя, компонент рассматривается как "черный ящик". Мы можем передать ему поведение пользователя, реквизиты и т. д. Этот "черный ящик" также будет соответствующим образом реагировать на определенные события и события. визуализированный вид может быть захвачен и просмотрен пользователем. Исследуя эти местоположения, мы можем увидеть, ведет ли себя компонент так, как мы хотим, гарантируя, что его поведение должно быть согласованным.
Еще одна тема, которую я хотел бы затронуть, заключается в том, чтоДух контракта. Как пользователь компонента, я использую ваш компонент, а значит, мы подписываем договор, все поведение этого компонента должно соответствовать тому, что вы описываете, и третьей неожиданной возможности не будет. В конце концов, в корпоративных проектах мы не любим сюрпризов. Пасхальное яйцо antd также является напоминанием всем. Это довольно креативно, что мы можем играть с такими технологиями, но такого рода общедоступные библиотеки классов, особенно те, которые используются предприятиями, все еще более креативны и уделяют внимание контрактам. говорить удивление. Даже если это библиотека компонентов, используемая внутри вашего предприятия, если она не признана всеми в бизнесе, вам не следует проводить такой опасный тест.
Хороший компонентный тест также может помочь нам определить те сюрпризы, которые мы создаем намеренно или ненамеренно.Мы не будем говорить о преднамеренных сюрпризах.Боюсь, это такие неожиданности, которые появляются непреднамеренно.Необходимые.
генерация документа
Вообще говоря, когда мы делаем проект библиотеки классов, будет соответствующая документация, для некоторых проектов достаточно документа README.md, а для некоторых может потребоваться несколько документов Markdown. Для таких проектов, как библиотеки компонентов, мы можем использовать инструменты документации, чтобы помочь в создании документации напрямую. Здесь рекомендуется Vuepress, который может быстро помочь нам завершить создание документов библиотеки компонентов. (vuepress.vuejs.org/zh/guide/)
Vuepress — это инструмент для создания документов Стиль по умолчанию почти такой же, как у официального документа vue, потому что первоначальное намерение его создания — обеспечить поддержку документов для vue и связанных с ним подпроектов. Он имеет встроенные расширения Markdown.При написании документов вы используете разметку для записи.Самое беззаботное то, что вы можете использовать компоненты Vue непосредственно в файлах Markdown, что означает, что компоненты, написанные в нашей библиотеке компонентов, могут быть написаны напрямую , Поместите его в документ, чтобы показать фактический эффект работы компонента. Сайт нашего кейса тоже написан через vuepress.После создания статического сайта используйтеgh-pagesРазверните прямо на github.
Одна из лучших особенностей vuepress заключается в том, что вы можете настроить его конфигурацию и темы веб-пакета, а это означает, что вы можете сделать так, чтобы ваш собственный сайт документации поддерживал больше функций на этапе разработки, и в то же время изменить стиль сайта на свой собственный набор стиль темы. Это избавляет нас от необходимости начинать новый набор с нуля, что весьма эффективно для нашей потребности быстро завершить создание документа библиотеки компонентов.
Однако это лишь вспомогательная вещь к тому, что мы собираемся делать, поэтому конкретное использование будет объяснено на практическом этапе и здесь повторяться не будет.
пользовательская тема
Функция настройки темы определенно хороша для библиотеки классов с открытым исходным кодом, чтобы пользователи могли использовать функцию библиотеки компонентов и использовать свой собственный стиль дизайна в дизайне интерфейса. На самом деле функциональный дизайн большинства библиотек компонентов достаточно завершен, поэтому, вообще говоря, даже если малые и средние компании хотят реализовать свой собственный набор стилей компонентов, они могут напрямую использовать библиотеки с открытым исходным кодом, такие как element, iview или react. -основанный Antd.Предоставленные функции и логика взаимодействия, а затем настройка темы на нем в основном соответствует потребностям (если у вашего дизайнера много идей...).
Общий способ использования функции пользовательской темы выглядит следующим образом.
- Через генератор тем. (Изготовителю необходимо сделать инструмент отдельно)
- Импортировать ключевые файлы темы, переопределяя переменные темы. (Этот метод обычно должен адаптироваться к препроцессору css, используемому производителем)
Для первого метода производитель библиотеки компонентов обычно создает набор вещей, которые генерируют стиль компонента в инструмент, а затем предоставляет его пользователю для настройки в соответствии с его собственными потребностями и, наконец, создает набор определенных файлов стилей. , Ввести в использование.
Второй способ,Как пользователь, вы в основном переопределяете некоторые переменные темы в библиотеке компонентов., потому что файл стиля конкретного компонента не является жестко заданным фиксированным значением стиля, а использует определенную переменную, поэтому ваша пользовательская тема вступит в силу. Но это также создает небольшую проблему, заключающуюся в том, что вам необходимо адаптировать препроцессор стиля, используемый создателем библиотеки компонентов. Например, если вы используете iview, ваш проект должен иметь возможность анализировать файлы Less. Если вы используете ElementUI, ваш проект будет Должен уметь анализировать SCSS.
На самом деле, первый метод в основном заключается в настройке переменных темы. Поэтому, когда мы хотим сами создать набор библиотек компонентов, несложно заметить, что ключевым моментом является необходимостьОтдельные файлы переменных темы и файлы стилей, последнее просто.
упаковка веб-пакета
При построении проекта библиотеки классов здесь упоминаются два момента:
- открытый вход
- Внешние зависимости
Поговорим о первом пункте «открытые интерфейсы». В бизнес-проектах весь наш проект упаковывается в один или несколько файлов пакетов с помощью веб-пакета или других инструментов упаковки, и эти файлы будут запускаться сразу после загрузки браузером. Но проект библиотеки классов часто запускается не отдельно, а путем выставления «записи», которую я затем вызываю в бизнес-проекте. В файле конфигурации веб-пакета вы можете определитьoutputсерединаlibraryа такжеlibraryTargetдля управления «входной переменной», которую мы хотим предоставить, и объектным кодом, который мы хотим построить.
Это можно упомянуть подробную информацию о официальной документации WebPack:Веб-пакет Просто .org/config как у ATI...
module.exports = {
// other config
output: {
library: "MyLibName",
libraryTarget: "umd",
umdNamedDefine: true
}
}
Давайте поговорим о «внешних зависимостях». Когда мы создаем проект библиотеки компонентов Vue, все наши компоненты зависят от Vue. Когда Vue вводится где-то в нашем проекте библиотеки компонентов, среда выполнения Vue упаковывается. Она также будет упакована вместе в окончательный файл комплекта библиотеки компонентов. Проблема в том, что наша библиотека компонентов vue используется проектом vue, поэтому в проекте уже есть среда выполнения, поэтому нам не нужно добавлять среду выполнения в библиотеку компонентов, что увеличит размер компонента. библиотечный комплект. с помощью веб-пакетаexternalsЗависимости Vue могут быть «экстернализированы».
module.exports = {
// other config
externals: {
vue: {
root: 'Vue',
commonjs: 'vue',
commonjs2: 'vue',
amd: 'vue'
}
}
}
нагрузка по требованию
Функция загрузки библиотеки компонентов по требованию по-прежнему очень практична, что может помешать нам упаковать весь используемый и неиспользуемый контент в бизнес-код в процессе использования библиотеки компонентов, что приведет к чрезмерному влиянию конечного файла пакета. , пользовательский опыт.
В бизнес-проектах наша загрузка по требованию состоит в том, чтобы генерировать кусок, который нужно загрузить по требованию, а затем, когда браузер запускает наш упакованный код, он обнаруживает, что нам нужен этот кусок ресурсов, и затем инициирует запрос на получение соответствующего ресурс.требуемый код.
В библиотеке компонентов нам нужно изменить метод введения.Например, когда мы вводим библиотеку компонентов, она напрямую вводится непосредственно в библиотеки компонентов и стили. Насколько
import LimeUI from 'lime-ui' // 引入组件库
import 'lime-ui/styles/index.css' // 引入整个组件库的样式文件
Vue.use(LimeUI)
Затем можно переключиться на ручную загрузку по запросу.
import { Button } from 'lime-ui' // 引入button组件
import 'lime-ui/styles/button.css' // 引入button的样式
Vue.component('l-button', Button) // 注册组件
Этот метод действительно импортируется по запросу, но также неудобно, что нам нужно вручную импортировать компоненты и стили каждый раз, когда мы импортируем. Вообще говоря, в проекте используется более десяти компонентов, что более проблематично. Как библиотека компонентов решает эту проблему?
С помощью плагина babel автоматизирован режим введения библиотек компонентов и стилей компонентов, таких как те, которые используются antd, antd-mobile и material-ui.babel-plugin-importи используется ElementUIbabel-plugin-component. После того, как плагин babel настроен в бизнес-проекте, он может сделать такое преобразование для вас внутри (здесь, babel-plugin-component).
// 原始代码
import { Button } from 'components'
// 转换代码
var button = require('components/lib/button')
require('components/lib/button/style.css')
Хорошо, так как код может быть преобразован таким образом, на самом деле все, что нам нужно сделать, это поместить код упаковки нашей библиотеки компонентов в соответствующую структуру файловых каталогов, когда мы собираем библиотеку компонентов. Пользователи могут загружать компоненты вручную или использовать плагин babel для оптимизации этого шага.
документация компонента babel-плагина:woohoo. эта лошадь plus.com/package/daddy…
документация по импорту babel-plugin:woohoo. эта лошадь plus.com/package/daddy…
Компоненты: по сравнению с ежедневным проектированием компонентов, что еще вам нужно знать, чтобы стать библиотекой компонентов?
Есть еще некоторые различия между навыками создания компонентов в библиотеке компонентов и теми, которые используются в проекте.Этот раздел должен рассказать вам, какой необходимый контент знаний мы должны знать о дизайне компонентов в библиотеке компонентов.
Обмен компонентами: что еще, кроме обмена данными между верхним и нижним уровнями?
Обычно мы используем компонентную коммуникацию черезpropsа также$emitдля передачи данных между родительским компонентом и дочерним компонентом, как показано на следующей схеме: родительский компонент передаетpropsПередать данные в подкомпоненты, подкомпоненты через$emitПередайте данные родительскому компоненту, максимум черезeventBusилиVuexДля достижения взаимной передачи данных между любыми компонентами. Эти методы более эффективны в обычном процессе разработки бизнеса, но немного неэффективны в процессе разработки библиотеки компонентов.Основные проблемы:Как обрабатывать межуровневую передачу данных между его компонентами?
Если в повседневных проектах мы, конечно, можем использовать что-то вродеvuexТаким образом, данные компонентов напрямую передаются на аутсорсинг для обеспечения межуровневого доступа к данным, ноvuexЭто всегда внешняя зависимость, и дизайн библиотеки компонентов не должен допускать существования такой сильной зависимости. Давайте поговорим о двух методах передачи данных, которые мы будем использовать в проекте библиотеки компонентов.
Встроенная функция предоставления/вставки
предоставление/внедрение — это набор решений, с которыми Vue поставляется для получения данных родительского компонента от дочерних компонентов на разных уровнях.Эта пара вещей похожа на одну в реакцииContextВсе, чтобы иметь дело с проблемой передачи данных компонентов по пересеченным уровнем.
При использовании данные, которые необходимо внедрить, объявляются в INJECT в подкомпоненте, а затем данные, необходимые для предоставления компонентов подкомпонента в месте в родительском компоненте. Независимо от того, сколько в них компонентов, дочерние компоненты могут получить соответствующие данные. (См. следующий пример псевдокода)
// 引用关系 CompA --> CompB --> CompC --> ... --> ChildComp
// CompA.vue
export default {
provide: {
theme: 'dark'
}
}
// CompB.vue
// CompC.vue
// ...
// ChildComp.vue
export default {
inject: ['theme'],
mounted() {
console.log(this.theme) // 打印结果: dark
}
}
Однако метод Provide/inject в основном заключается в том, что дочерний компонент получает свое состояние от родительского компонента по всему уровню, но он не может идеально решить следующие проблемы:
- Дочерние компоненты передают данные между уровнями родительским компонентам
- Родительские компоненты передают данные между уровнями дочерним компонентам
Отправка и вещание: Самодельные функции отправки и вещания
диспетчеризация и широковещательная рассылка могут использоваться для межуровневой связи между родительским и дочерним компонентами.. В vue1.x есть функции отправки и вещания, но в vue2.x их убрали. Здесь вы можете обратиться к содержимому v1.x, указанному в ссылке ниже.
диспетчерская документация (v1.x):V1.v UE JS.org/API/#VM-третий…
документация по трансляции (v1.x):V1.v UE JS.org/API/#VM — вроде о...
По документации мы знаем, что
-
диспетчеризация отправит событие, которое сначала запускается в его собственном экземпляре компонента, а затем поднимается уровень за уровнем по родительской цепочке, пока не будет запущен прослушиватель для этого события, объявленного в родительском. Затем остановитесь, если прослушиватель не вернет true. Конечно, прослушиватель также может получить все переданные параметры, когда событие отправляется через функцию обратного вызова. Это очень похоже на наш механизм всплытия событий в DOM, и его нетрудно понять.
-
Трансляция состоит в том, чтобы транслировать событие на все свои собственные экземпляры подкомпонентных компонентов и снижать слой по слою. Из-за дерева компонентов, процесс спускания будет встречаться с «вилкой», который можно рассматривать как полосу нескольких Пути. Событие пузырирует каждый подпунктер, останавливается, когда слушатель срабатывает на каждом пути, и продолжает распространять вниз, если слушатель возвращает True.
Кратко обобщить.Событие отправки диспетчеризации поднимается вверх, событие широковещательной рассылки распространяется вниз, и когда оно встречает прослушиватель, который обрабатывает соответствующее событие, оно будет обработано.Если прослушиватель не возвращает true, он останавливается.
Следует отметить, что события отправки и трансляции здесьмежуровневый, и может содержать параметры, что означает, что вы можетеПередача данных между слоями.
Поскольку диспетчеризация и широковещательная рассылка отменены в vue2.x, мы можем написать один здесь, а затем смешать его с компонентами, которые должны использовать межуровневую связь между компонентами через миксин.
Содержание метода на самом деле очень простое, вот непосредственно код
// 参考自iview的实现
function broadcast(componentName, eventName, params) {
this.$children.forEach(child => {
const name = child.$options.name;
if (name === componentName) {
child.$emit.apply(child, [eventName].concat(params));
} else {
broadcast.apply(child, [componentName, eventName].concat([params]));
}
});
}
export default {
methods: {
dispatch(componentName, eventName, params) {
let parent = this.$parent || this.$root;
let name = parent.$options.name;
while (parent && (!name || name !== componentName)) {
parent = parent.$parent;
if (parent) {
name = parent.$options.name;
}
}
if (parent) {
parent.$emit.apply(parent, [eventName].concat(params));
}
},
broadcast(componentName, eventName, params) {
broadcast.call(this, componentName, eventName, params);
}
}
};
На самом деле реализация здесь отличается от реализации в vue1.x:
- диспетчеризация не имеет всплывающих событий. Выполнить любой найденный
- Параметр имени настроен на запуск событий только для компонентов с определенным именем.
На самом деле, если вы понимаете код здесь, вы должны быть в состоянии понять его.Способ найти любой компонент, смотрит ли он вверх или вниз, представляет собой не что иное, как обход цикла и итеративную обработку до тех пор, пока не появится целевой компонент, а затем вызовите его.Диспетчеризация и широковещательная передача — это не что иное, как использование механизма событий, который поставляется с Vue, для публикации события после его обнаружения, а затем прослушивания события в определенных компонентах и его обработки.
Функция рендеринга: раскрывает всю мощь javascript
Сначала давайте рассмотрим, как компонент проходит путь от написания кода до преобразования в интерфейс. Когда мы пишем однофайловые компоненты Vue, обычно есть три части: шаблон, скрипт и стиль.При упаковке vue-loader сначала скомпилирует часть шаблона шаблона в код для построения представления, требуемого параметром рендеринга в экземпляре Vue. . При запуске среда выполнения vue будет использовать$mountВизуализируйте его и смонтируйте под узлом DOM, который вы предоставили после рендеринга.
В течение всего процесса мы ежедневно уделяем наибольшее внимание только части шаблона, но шаблон на самом деле просто синтаксический сахар, предоставляемый Vue, Он просто позволяет нам писать код так же легко, как писать html, снижая стоимость обучения. новых партнеров Vue. React не предоставляет синтаксический сахар для шаблона, но использует JSX для упрощения написания компонентов. (vue может появиться под давлением двух фреймворков react и angular, и определенную роль в его продвижении играет лаконичный и понятный синтаксис шаблона, ведь он выглядит проще)
Благодаря тому, что мы рассмотрели выше, мы действительно обнаружили, чтоШаблоны, которые мы пишем, в конечном счете, являются javascript. После того, как здесь скомпилирован шаблон, задается функция рендеринга, и при выполнении рендеринга vue будет выполнять операции в рендере для рендеринга наших компонентов.
Так что с шаблонами все в порядке, но если вы хотите использовать всю мощь javascript, вы можете использовать функции рендеринга.
Функция рендеринга и JSX (официальная документация):Talent.v ue js.org/v2/expensive/hot…
Для ежедневного написания бизнес-компонентов мы можем использовать шаблон, но при возникновении сложных ситуаций используйте写组件 --> 引入使用 --> 注册组件 --> 使用组件Метод не прост в обращении, например, в следующих двух ситуациях:
- Динамический компонент рендеринга через код
- Визуализация компонента в другом месте
Первый случай — это динамический рендеринг компонентов через код, например часто используемую в операциях страницу h5 активности.Каждая активность индивидуальна, и каждый раз она либо переделывается, либо модифицируется на исходной основе. Однако корректировка структуры страницы этой модификации очень велика, и она каждый раз будет деструктивной, и ничем не отличается от переделки. В этом случае, независимо от содержания каждого действия, передняя часть должна начать писать код. Но на самом деле нужно сделать активным только редактор в фоне управления, содержимое редактора напрямую конвертируется в код функции рендеринга, а затем через конфигурацию отправляется на определенную страницу, а страница-носитель получает данные и отправляет его в функцию рендеринга для рендеринга. Таким образом, содержимое компонента может динамически отображаться в соответствии со способом управления фоновой конфигурацией, а каждая активная страница и операция также могут генерироваться редактором.
Второй случай — когда вы хотите отобразить компонент в другом месте. Наше ежедневное написание бизнес-компонентов в основном состоит в том, чтобы написать компонент и использовать его по мере необходимости. Если вы просто напишете компонент в шаблоне, содержимое вашего компонента будет отображаться как подкомпонент текущего компонента, а сгенерированная структура DOM также находится под текущей структурой DOM. Зная рендеринг, мы можем фактически создать новый экземпляр vue и после динамического рендеринга вручную смонтировать его в любое место DOM.
import CompA from './CompA.vue'
let Instance = new Vue({
render(h) {
return h(CompA)
}
})
let component = Instance.$mount() // 执行渲染
document.body.appendChild(component.$el) // 挂载到body元素下
Внутри элемента, который мы используемthis.$messageИспользуется динамический рендеринг, а затем вручную монтируется в указанное место.
Практикуйтесь: сделайте это один раз, и вы
Здесь сначала вставьте наш адрес github, вы можете проверить его в процессе.GitHub.com/Arron KL пока/приходите…
Построить инженерный проект
Первым шагом является создание инженерной структуры
Здесь нет никакой ерунды, просто вставьте структуру каталогов и объяснение
|- assets/ # 存放一些额外的资源文件,图片之类的
|- build/ # webpack打包配置
|- docs/ # 存放文档
|- .vuepress # vuepress配置目录
|- component # 组件相关的文档放这里
|- README.md # 静态首页
|- lib/ # 打包生成的文件放这里
|- styles/ # 打包后的样式文件
|- src/ # 在这里写代码
|- mixins/ # mixin文件
|- packages/ # 各个组件,每个组件是一个子目录
|- styles/ # 样式文件
|- common/ # 公用的样式内容
|- mixins/ # 复用的mixin
|- utils # 工具目录
|- index.js # 打包入口,组件的导出
|- test/ # 测试文件夹
|- specs/ # 存放所有的测试用例
|- .npmignore
|- .gitignore
|- .babelrc
|- README.md
|- package.json
Более важным каталогом здесь является наш каталог src, в котором хранятся наши отдельные компоненты и набор библиотек стилей, а также некоторые вспомогательные вещи. Когда мы пишем документацию, мы пишем ее в каталоге docs. Самый внешний уровень каталога проекта — это некоторый общий контент конфигурации, такой как.npmignoreа также.gitignoreТакие файлы очень распространены, поэтому я не буду подробно останавливаться на этой части, если у вас есть какие-то сомнения, вы можете напрямую обратиться к исходному коду на github для сравнения.
Здесь нам нужно установить хорошую библиотеку файлов Esen
Создайте файл emitter.js в src/mixins и напишите следующий контент, то есть наши методы отправки и трансляции, которые будут использоваться в последующем дизайне компонента.
function broadcast(componentName, eventName, params) {
this.$children.forEach(child => {
const name = child.$options.name;
if (name === componentName) {
child.$emit.apply(child, [eventName].concat(params));
} else {
broadcast.apply(child, [componentName, eventName].concat([params]));
}
});
}
export default {
methods: {
dispatch(componentName, eventName, params) {
let parent = this.$parent || this.$root;
let name = parent.$options.name;
while (parent && (!name || name !== componentName)) {
parent = parent.$parent;
if (parent) {
name = parent.$options.name;
}
}
if (parent) {
parent.$emit.apply(parent, [eventName].concat(params));
}
},
broadcast(componentName, eventName, params) {
broadcast.call(this, componentName, eventName, params);
}
}
};
Затем создайте новый файл Assist.js в папке src/utils и запишите вспомогательные функции.
export function oneOf(value, validList) {
for (let i = 0; i < validList.length; i++) {
if (value === validList[i]) {
return true;
}
}
return false;
}
Эти два места будут использоваться позже.Если вам нужен другой вспомогательный контент, вы также можете создать их в каталоге, где находятся эти два файла.
Второй шаг – улучшить процесс упаковки.
После того, как директория построена, пришло время залить ее из плоти и крови.Чтобы упаковать проект библиотеки компонентов, мы должны сначала настроить наш веб-пакет, иначе он не сможет запуститься после написания исходного кода. Итак, мы сначала находим каталог сборки и создаем три файла в каталоге сборки.
-
веб-пакет.base.js . Сохраните некоторые базовые настройки правил
-
webpack.prod.js . Упаковка конфигурации всей библиотеки компонентов
-
gen-style.js . Индивидуальные стили упаковки
Ниже приведено конкретное содержимое конфигурации.
/* webpack.base.js */
const path = require('path');
const webpack = require('webpack');
const pkg = require('../package.json');
const VueLoaderPlugin = require('vue-loader/lib/plugin')
function resolve(dir) {
return path.join(__dirname, '..', dir);
}
module.exports = {
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
css: [
'vue-style-loader',
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
],
less: [
'vue-style-loader',
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
{
loader: 'less-loader',
options: {
sourceMap: true,
},
},
],
},
postLoaders: {
html: 'babel-loader?sourceMap'
},
sourceMap: true,
}
},
{
test: /\.js$/,
loader: 'babel-loader',
options: {
sourceMap: true,
},
exclude: /node_modules/,
},
{
test: /\.css$/,
loaders: [
{
loader: 'style-loader',
options: {
sourceMap: true,
},
},
{
loader: 'css-loader',
options: {
sourceMap: true,
},
}
]
},
{
test: /\.less$/,
loaders: [
{
loader: 'style-loader',
options: {
sourceMap: true,
},
},
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
{
loader: 'less-loader',
options: {
sourceMap: true,
},
},
]
},
{
test: /\.scss$/,
loaders: [
{
loader: 'style-loader',
options: {
sourceMap: true,
},
},
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
]
},
{
test: /\.(gif|jpg|png|woff|svg|eot|ttf)\??.*$/,
loader: 'url-loader?limit=8192'
}
]
},
resolve: {
extensions: ['.js', '.vue'],
alias: {
'vue': 'vue/dist/vue.esm.js',
'@': resolve('src')
}
},
plugins: [
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.DefinePlugin({
'process.env.VERSION': `'${pkg.version}'`
}),
new VueLoaderPlugin()
]
};
/* webpack.prod.js */
const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const webpackBaseConfig = require('./webpack.base.js');
process.env.NODE_ENV = 'production';
module.exports = merge(webpackBaseConfig, {
devtool: 'source-map',
mode: "production",
entry: {
main: path.resolve(__dirname, '../src/index.js') // 将src下的index.js 作为入口点
},
output: {
path: path.resolve(__dirname, '../lib'),
publicPath: '/lib/',
filename: 'lime-ui.min.js', // 改成自己的类库名
library: 'lime-ui', // 类库导出
libraryTarget: 'umd',
umdNamedDefine: true
},
externals: { // 外部化对vue的依赖
vue: {
root: 'Vue',
commonjs: 'vue',
commonjs2: 'vue',
amd: 'vue'
}
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': '"production"'
})
]
});
/* gen-style.js */
const gulp = require('gulp');
const cleanCSS = require('gulp-clean-css');
const sass = require('gulp-sass');
const rename = require('gulp-rename');
const autoprefixer = require('gulp-autoprefixer');
const components = require('./components.json')
function buildCss(cb) {
gulp.src('../src/styles/index.scss')
.pipe(sass())
.pipe(autoprefixer())
.pipe(cleanCSS())
.pipe(rename('lime-ui.css'))
.pipe(gulp.dest('../lib/styles'));
cb()
}
exports.default = gulp.series(buildCss)
Хорошо, здесь наша конфигурация веб-пакета в основном настроена. Конфигурация в webpack.base.js в основном является конфигурацией некоторых загрузчиков и плагинов. Конкретные вход и выход настраиваются в webpack.prod.js. Здесь webpack.prod.js объединяет элементы конфигурации в webpack.base.js. Что касается output.libary и externals, то это должно быть знакомо тем, кто читал содержание предыдущего этапа «подготовки».
Кроме того, есть gen-style.js. Этот файл использует только gulp для упаковки файлов стилей. Здесь мы используем синтаксис scss. Если вы хотите использовать меньше или другие препроцессоры, вы также можете изменить его самостоятельно. файлы и связанные с ними зависимости.
Однако на этом настройка точно еще не закончена, для начала нам необходимо установить сюда различные загрузчики и плагины, используемые в конфигурации. Чтобы не пропустить элементы установки и сохранить согласованность, вы можете напрямую скопировать следующее содержимое конфигурации и поместить его в package.json черезnpm installустановить. Обратите внимание, что после завершения установки здесь, на самом деле, зависит от содержимого, некоторые из последних также устанавливаются вместе.
"dependencies": {
"async-validator": "^3.0.4",
"core-js": "2.6.9",
"webpack": "^4.39.2",
"webpack-cli": "^3.3.7"
},
"devDependencies": {
"@babel/core": "^7.5.5",
"@babel/plugin-transform-runtime": "^7.5.5",
"@babel/preset-env": "^7.5.5",
"@vue/test-utils": "^1.0.0-beta.29",
"babel-loader": "^8.0.6",
"chai": "^4.2.0",
"cross-env": "^5.2.0",
"css-loader": "2.1.1",
"file-loader": "^4.2.0",
"gh-pages": "^2.1.1",
"gulp": "^4.0.2",
"gulp-autoprefixer": "^7.0.0",
"gulp-clean-css": "^4.2.0",
"gulp-rename": "^1.4.0",
"gulp-sass": "^4.0.2",
"karma": "^4.2.0",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^3.1.0",
"karma-coverage": "^2.0.1",
"karma-mocha": "^1.3.0",
"karma-sinon-chai": "^2.0.2",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "^0.0.32",
"karma-webpack": "^4.0.2",
"less": "^3.10.2",
"less-loader": "^5.0.0",
"mocha": "^6.2.0",
"node-sass": "^4.12.0",
"rimraf": "^3.0.0",
"sass-loader": "^7.3.1",
"sinon": "^7.4.1",
"sinon-chai": "^3.3.0",
"style-loader": "^1.0.0",
"url-loader": "^2.1.0",
"vue-loader": "^15.7.1",
"vue-style-loader": "^4.1.2",
"vuepress": "^1.0.3"
},
Кроме того, поскольку мы используем babel, нам нужно установить его в корневой каталог проекта..babelrcфайл со следующим содержимым:
{
"presets": [
[
"@babel/preset-env",
{
"loose": false,
"modules": "commonjs",
"spec": true,
"useBuiltIns": "usage",
"corejs": "2.6.9"
}
]
],
"plugins": [
"@babel/plugin-transform-runtime",
]
}
Конечно, не забудьте прописать скрипты в файле package.json, чтобы упростить процесс ручного ввода команд.
{
"scripts": {
"build:style": "gulp --gulpfile build/gen-style.js",
"build:prod": "webpack --config build/webpack.prod.js",
}
}
Третий шаг — создание инструмента документации.
Если vuepress не был установлен на предыдущем шаге, вы можете пройтиnpm install vuepress --save-devустановить,
Затем добавьте скрипт в Package.json, запустите скорость
{
"scripts": {
// ...
"docs:dev": "vuepress dev docs",
"docs:build": "vuepress build docs"
}
}
На этом этапе вы можете написать что-нибудь в файле docs/README.md и запуститьnpm run docs:devВы можете увидеть содержимое локального документа. Использовать при упаковкеnpm run docs:buildВот и все.
Если наш проект должен быть размещен на github, то мы также можем разместить наш документ на github после его создания и использовать функцию страниц github, чтобы этот локальный документ работал в Интернете. (страницы github размещают наши статические страницы и ресурсы)
может бежатьnpm install gh-pages --save-devУстановитьgh-pagesЭтот инструмент может помочь нам развернуть документы страниц github одним щелчком мыши. Его принцип работы заключается в переносе ресурсов из соответствующей папки в ветку gh-pages нашего текущего проекта, а затем после того, как эта ветка будет отправлена на github, github будет обслуживать содержимое ветки. Чтобы использовать его лучше, мы можем добавить скрипты в package.json.
{
"scripts": {
// ...
"deploy": "gh-pages -d docs/.vuepress/dist",
"deploy:build": "npm run docs:build && npm run deploy",
}
}
Таким образом, вы можете использоватьnpm run deployРазверните статический сайт, сгенерированный vuepress, напрямую, но обязательно запустите сборщик документации перед развертыванием. Поэтому мы также добавилиnpm run deploy:buildэту команду можно использовать для непосредственного совместного решения построения и развертывания документа. Это очень просто?
Однако для того, чтобы мы могли использовать написанные нами компоненты напрямую, нам также нужно немного настроить vuepress. Создайте новый файлEnhanceApp.js в каталоге docs/.vuepress, напишите следующий контент и добавьте в него запись и стили нашей библиотеки компонентов.
import LimeUI from '../../src/index.js'
import "../../src/styles/index.scss"
export default ({
Vue,
options,
router
}) => {
Vue.use(LimeUI)
}
На данный момент компоненты, которые мы напишем позже, можно использовать непосредственно в документе.
Четвертый шаг, построение стиля
Первое, что нужно отметить, это то, что синтаксис препроцессора стилей, который мы здесь используем, — scss. Затем в разделе «Улучшение процесса упаковки» приведен код для упаковки с помощью gulp, но необходимо объяснить, как мы интегрируем содержимое стилей.
First of all, after doing loads in order to facilitate on-demand, for the style of each component is a separate scss file, write the style of the time, in order to avoid too many levels of nesting, using BEM-style way to записывать.
Нам нужно выполнить следующую команду в каталоге src/styles, чтобы сгенерировать базовый файл стиля.
cd src/styles
mkdir common
mkdir mixins
touch common/var.scss # 样式变量文件
touch common/mixins.scss
touch index.scss # 引入所有样式
Затем заполните соответствующие файлы var.scss и mixins.scss базовым содержимым.
/* common/var.scss */
$--color-primary: #ff6b00 !default;
$--color-white: #FFFFFF !default;
$--color-info: #409EFF !default;
$--color-success: #67C23A !default;
$--color-warning: #E6A23C !default;
$--color-danger: #F56C6C !default;
/* mixins/mixins.scss */
$namespace: 'lime'; /* 组件库的样式前缀 */
/* BEM
-------------------------- */
@mixin b($block) {
$B: $namespace+'-'+$block !global;
.#{$B} {
@content;
}
}
В файле миксинов мы объявляем миксин, который поможет нам лучше создавать файлы стилей.
Случай сборки компонента
Вышеупомянутый контент установлен, мы можем начать делать конкретный компонент, чтобы попробовать
Простой компонент кнопки
Это общий эффект после того, как это сделано
Хорошо, затем мы создаем файлы, связанные с основным компонентом кнопки.
cd src/packages
mkdir button && cd button
touch index.js
touch button.vue
Напишите содержимое button.vue
<template>
<button class="lime-button" :class="{[`lime-button-${type}`]: true}" type="button">
<slot></slot>
</button>
</template>
<script>
import { oneOf } from '../../utils/assist';
export default {
name: 'Button',
props: {
type: {
validator (value) {
return oneOf(value, ['default', 'primary', 'info', 'success', 'warning', 'error']);
},
type: String,
default: 'default'
}
}
}
</script>
Здесь нам нужно экспортировать этот компонент в index.js
import Button from './button.vue'
export default Button
Таким образом завершается один компонент, а затем вы можете попробовать еще несколько компонентов, но одно но, что этим компонентам нужна единая запись упаковки, которую мы уже настроили в веб-пакете, то есть src/index.js. В этом файл, нам нужно импортировать компонент кнопки, который мы только что написали, и другие компоненты, которые вы написали в этом файле, а затем экспортировать их в веб-пакет для упаковки.Конкретный код выглядит следующим образом
import Button from './packages/button'
const components = {
lButton: Button,
}
const install = function (Vue, options = {}) {
Object.keys(components).forEach(key => {
Vue.component(key, components[key]);
});
}
export default install
Видно, что в конечном итоге мы экспортировали в index.js функцию install, которая на самом деле представляет собой способ написания плагина Vue, который нам удобно использовать, когда мы внедряем его в реальный проект.Vue.useспособ автоматической установки всей нашей библиотеки компонентов. install принимает два параметра, один из которых Vue, который мы используем для регистрации компонентов один за другим. Также есть опции, чтобы мы могли передавать некоторые параметры инициализации при регистрации компонентов, например размер кнопки по умолчанию, тему и другую информацию, которая может быть установлена параметрами.
Затем мы можем создать новый файл button.scss в каталоге src/styles и написать стиль, соответствующий нашей кнопке.
/* button.scss */
@charset "UTF-8";
@import "common/var";
@import "mixins/mixins";
@include b(button) {
min-width: 60px;
height: 36px;
font-size: 14px;
color: #333;
background-color: #fff;
border-width: 1px;
border-radius: 4px;
outline: none;
border: 1px solid transparent;
padding: 0 10px;
&:active,
&:focus {
outline: none;
}
&-default {
color: #333;
border-color: #555;
&:active,
&:focus,
&:hover {
background-color: rgba($--color-primary, 0.3);
}
}
&-primary {
color: #fff;
background-color: $--color-primary;
&:active,
&:focus,
&:hover {
background-color: mix($--color-primary, #ccc);
}
}
&-info {
color: #fff;
background-color: $--color-info;
&:active,
&:focus,
&:hover {
background-color: mix($--color-info, #ccc);
}
}
&-success {
color: #fff;
background-color: $--color-success;
&:active,
&:focus,
&:hover {
background-color: mix($--color-success, #ccc);
}
}
}
Наконец, нам также нужно добавить стиль кнопки в файл src/styles/index.scss.
@import "button";
Для простого эксперимента вы можете написать два компонента кнопок прямо в файле docs/README.md и попробовать их.
<template>
<l-button type="primary">Click me</l-button>
</template>
Если ты хочешь быть со мнойarronkler.github.io/lime-ui/Тот же эффект, что и выше, вы можете обратиться кGitHub.com/Arron KL пока/приходите…Конфигурация в каталоге документов проекта. Если вам нужна более персонализированная конфигурация, вы можете обратиться к официальной документации vuepress.
УВЕДОМЛЕНИЕ компонент подсказки
Этот компонент будет использовать наши вещи, связанные с динамическим рендерингом. Окончательное использование выглядит следующим образом
this.$notice({
title: '提示',
content: this.content || '内容',
duration: 3
})
Эффект похож на этот
Хорошо, давайте сначала напишем базовый исходный код этого компонента.
Создайте новую папку извещения в каталоге src/packages, а затем создайте новый файл извещения.vue.
<template>
<div class="lime-notice">
<div class="lime-notice__main" v-for="item in notices" :key="item.id">
<div class="lime-notice__title">{{item.title}}</div>
<div class="lime-notice__content">{{item.content}}</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
notices: []
}
},
methods: {
add(notice) {
let id = +new Date()
notice.id = id
this.notices.push(notice)
const duration = notice.duration
setTimeout(() => {
this.remove(id)
}, duration * 1000)
},
remove(id) {
for(let i = 0; i < this.notices.length; i++) {
if (this.notices[i].id === id) {
this.notices.splice(i, 1)
break;
}
}
}
}
}
</script>
Код очень простой.По сути, он объявляет контейнер, а затем отображает и скрывает его, управляя данными уведомлений.Затем мы создаем новый файл note.js в той же директории для динамического рендеринга.
import Vue from 'vue'
import Notice from './notice.vue'
Notice.newInstance = (properties) => {
let props = properties || {}
const Instance = new Vue({
render(h) {
return h(Notice, {
props
})
}
})
const component = Instance.$mount()
document.body.appendChild(component.$el)
const notice = component.$children[0]
return {
add(_notice) {
notice.add(_notice)
},
remove(id) {
}
}
}
let noticeInstance
export default (_notice) => {
noticeInstance = noticeInstance || Notice.newInstance()
noticeInstance.add(_notice)
}
Здесь мы используем динамическую отрисовку, чтобы позволить нашим компонентам напрямую прикрепляться к телу, а не принадлежать корневой точке монтирования.
Затем создайте новый файл note.scss в каталоге src/styles и напишите наш файл стилей.
/* notice.scss */
@charset "UTF-8";
@import "common/var";
@import "mixins/mixins";
@include b(notice) {
position: fixed;
right: 20px;
top: 60px;
z-index: 1000;
&__main {
min-width: 100px;
padding: 10px 20px;
box-shadow: 0 0 4px #aaa;
margin-bottom: 10px;
border-radius: 4px;
}
&__title {
font-size: 16px;
}
&__content {
font-size: 14px;
color: #777;
}
}
Наконец, аналогичным образом необходимо обработать уведомление в файле ввода src/index.js. Полный код такой.
import Button from './packages/button'
import Notice from './packages/notice/notice.js'
const components = {
lButton: Button
}
const install = function (Vue, options = {}) {
Object.keys(components).forEach(key => {
Vue.component(key, components[key]);
});
Vue.prototype.$notice = Notice;
}
export default install
Мы можем видеть, что мы подключили наш прототип Vue к нашему$noticeметод, когда этот метод вызывается, он запускает набор процессов для динамического рендеринга компонентов в файле note.js. В настоящее время мы можем протестировать его в документе docs/README.md.
<script>
export default() {
mounted() {
this.$notice({
title: '提示',
content: this.content,
duration: 3
})
}
}
<script>
Упаковать стили и компоненты по отдельности
Для поддержки функции загрузки по требованию помимо упаковки всей библиотеки компонентов нам также необходимо упаковать стили и компоненты в один файл. Здесь нам нужно сделать две вещи
- Упаковка отдельных файлов css
- Упаковка отдельных компонентов
В первую очередь нам нужно создать файл / gen-style.js, чтобы сделать некоторую реконструкцию, плюс задача BuildSeperateCss, полный код выглядит следующим образом
// 其他之前的代码...
function buildSeperateCss(cb) {
Object.keys(components).forEach(compName => {
gulp.src(`../src/styles/${compName}.scss`)
.pipe(sass())
.pipe(autoprefixer())
.pipe(cleanCSS())
.pipe(rename(`${compName}.css`))
.pipe(gulp.dest('../lib/styles'));
})
cb()
}
exports.default = gulp.series(buildCss, buildSeperateCss) // 加上 buildSeperateCss
Что касается второго пункта, мы можем справиться с новой конфигурацией веб-пакета, создать новый файл build/webpack.component.js, написать
const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const webpackBaseConfig = require('./webpack.base.js');
const components = require('./components.json')
process.env.NODE_ENV = 'production';
const basePath = path.resolve(__dirname, '../')
let entries = {}
Object.keys(components).forEach(key => {
entries[key] = path.join(basePath, 'src', components[key])
})
module.exports = merge(webpackBaseConfig, {
devtool: 'source-map',
mode: "production",
entry: entries,
output: {
path: path.resolve(__dirname, '../lib'),
publicPath: '/lib/',
filename: '[name].js',
chunkFilename: '[id].js',
// library: 'lime-ui',
libraryTarget: 'umd',
umdNamedDefine: true
},
externals: {
vue: {
root: 'Vue',
commonjs: 'vue',
commonjs2: 'vue',
amd: 'vue'
}
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': '"production"'
})
]
});
Здесь мы ссылаемся на файл с именем component.json в папке сборки. Этот файл используется мной для идентификации наших компонентов и путей к компонентам. Фактически, вы также можете напрямую пройти через каталог src/packages через скрипт, чтобы автоматически получить это некоторое Информация. Вот простая демонстрация, код build/component.json выглядит следующим образом
{
"button": "packages/button/index.js",
"notice": "packages/notice/notice.js"
}
После того, как все отдельные процессы упаковки настроены, мы можем добавить команду scripts в файл package.json.
{
"scripts": {
// ...
"build:components": "webpack --config build/webpack.component.js",
"dist": "npm run build:style && npm run build:prod && npm run build:components",
}
}
Хорошо, теперь просто нужно запуститьnpm run distКоманда автоматически создаст полное содержимое стиля и индивидуальное содержимое стиля каждого компонента, а затем упакует полный пакет компонента и отдельный пакет для каждого компонента.
Одно следует отметить, что эти поля в вашем package.json файл должны быть отрегулированы
{
"name": "lime-ui",
"version": "1.0.0",
"main": "lib/lime-ui.min.js",
//...
}
Среди них имя указывает имя пакета, когда другие используют ваш пакет, а главное поле очень важно, указывающее, какой файл входа используется, когда кто-то напрямую импортирует ваш пакет. Здесь, потому что наш упакованный файл веб-пакета — lib/lime-ui.min.js, поэтому мы устанавливаем его следующим образом.
Когда все на месте, можно запускатьnpm run distупакуйте библиотеку компонентов, затемnpm publishПерейдите к публикации вашей библиотеки компонентов (требуется перед публикациейnpm loginавторизоваться)
Используйте собственную библиотеку компонентов
Использовать напрямую
Мы можем использовать vue-cli или другие инструменты для создания другого демонстрационного проекта и использовать этот проект для импорта нашей библиотеки компонентов. Если ваш пакет еще не выпущен, вы можете использовать его в каталоге проекта вашей библиотеки компонентов с помощьюnpm linkилиyarn linkкоманда для создания ссылки (рекомендуется пряжа)
Затем в вашем демонстрационном каталоге используйтеnpm link package_nameилиyarn link package_nameЗдесь package_name — это имя пакета вашей библиотеки компонентов, а затем в файле входа вашего демонстрационного проекта.
import Vue from vue
import LimeUI from 'lime-ui'
import 'lime-ui/lib/styles/lime-ui.css'
// 其他代码 ...
Vue.use(LimeUI)
После того, как это настроено, созданные нами компоненты можно использовать в этом проекте.
нагрузка по требованию
То, о чем мы говорили выше, — это метод использования глобальной загрузки, так как же загрузить его по требованию? На самом деле, мы сказали, что раньше
Сначала установите его через npmbabel-plugin-componentpackage, то в вашем демонстрационном проекте.babelrcЗапишите эту часть в файл
{
"plugins": [
["component", {
"libraryName": "lime-ui",
"libDir": "lib",
"styleLibrary": {
"name": "styles",
"base": false, // no base.css file
"path": "[module].css"
}
}]
]
}
Конфигурация здесь должна соответствовать структуре каталогов нашего Lime-UI. С этой конфигурацией мы можем загружать по требованию. Вы можете загрузить кнопку, как это
import Vue from 'vue'
import { Button } from 'lime-ui'
Vue.component('a-button', Button)
Как видите, мы не загружаем никакие стили в этом месте, потому чтоbabel-plugin-componentЭто было сделано за нас, но поскольку мы только устанавливаем метод установки в точке входа библиотеки компонентов для регистрации компонента, когда мы вводим его по мере необходимости, нам нужно зарегистрировать его вручную.
Настройка темы
После того, как предыдущий контент сделан, настройка темы относительно проста.Сначала мы создаем файл global.scss в том же каталоге, что и входной файл проекта DEMO, а затем пишем в нем код, подобный следующему.
$--color-primary: red;
@import "~lime-ui/src/styles/index.scss";
Затем измените способ импорта библиотеки компонентов в файле ввода.
import Vue from vue
import LimeUI from 'lime-ui'
import './global.scss'
// 其他代码 ...
Vue.use(LimeUI)
Мы импортируем стиль библиотеки компонентов в файл ввода и меняем его, чтобы импортировать наш пользовательский файл global.scss.
На самом деле, это переопределяет значение переменной в var.scss в проекте библиотеки компонентов, а затем базовые стили остальных компонентов по-прежнему используют свое собственное содержимое стилей, чтобы можно было добиться настройки темы.
Эпилог
Посредством введения некоторых функций библиотеки компонентов и фактического примера эксплуатации в этой статье излагаются некоторые основные моменты для создания библиотеки компонентов. Я надеюсь, что благодаря такому совместному использованию мы сможем не только использовать библиотеку компонентов, но и узнать процесс рождения библиотеки компонентов и понять некоторые внутренние характеристики библиотеки компонентов, чтобы мы могли «знать» в процессе ежедневного использования. Когда возникает проблема или требования к библиотеке компонентов могут не выполняться, достаточно иметь новую отправную точку для размышлений.
Справочник по цитированию
- Vue
$dispatchа также$broadcastПодробно:nuggets.capable/post/684490… - Component Tests with Vue.js - Matt O'Connell : Woohoo.YouTube.com/watch?V=o IP…
- Буклет Nuggets: Компоненты Vue.js
- ЭЛЕМЕНТЫ:GitHub.com/E?Fe/Голодный…
- просмотр:github.com/iview/iview