Предисловие:
Компонентизация интерфейса — одна из горячих тем сегодня, а также проблема, с которой мы часто сталкиваемся при разработке одностраничных приложений.Теперь у нас есть очень хорошо функционирующий Element-UI. Различные крупные производители также один за другим анонсировали XXX-UI с открытым исходным кодом. Но есть и некоторые проблемы, например, каждой компании могут потребоваться разные бизнес-компоненты, или мы хотим разработать собственную библиотеку компонентов, чтобы повысить управляемость компонентами. Итак, как мы это делаем? Вот запись процесса сборки библиотеки компонентов с нуля.На данный момент есть только несколько простых компонентов, но я тоже буду потихоньку обновлять и поддерживать.
Адрес проекта на гитхабе:github
Адрес демонстрации проекта:демо
1. Подготовка окружающей среды
Чтобы создать библиотеку компонентов, нам нужно подготовить ряд сред.Во-первых, нам нужно рассмотреть следующие вопросы:
- Как построить строительные леса
- Как спланировать структуру каталогов
- Как писать документацию
Во-первых, для среды скаффолдинга уже есть очень зрелый официальный скаффолдинг Vue, мы просто используем его.
# 全局安装 vue-cli
$ npm install --global vue-cli
# 创建一个基于 webpack 模板的新项目
$ vue init webpack my-project
# 安装依赖,走你
$ cd my-project
$ npm install
$ npm run dev
Тогда давайте посмотрим на второй вопрос, как спланировать созданную нами структуру каталогов? Сначала нам нужен каталог для хранения компонентов и каталог для хранения примеров. Итак, нам нужно изменить структуру проекта, сгенерированную vue-cli:
.
...
|-- examples // 原 src 目录,改成 examples 用作示例展示
|-- packages // 新增 packages 用于编写存放组件
...
.
В этом случае нам нужно внести некоторые коррективы в наш конфигурационный файл webpack: во-первых, изменить каталог, где исходная компиляция указывает на src, на examples, а во-вторых, для того, чтобыnpm run build
Для нормальной компиляции пакетов нам также нужно добавить еще один каталог компиляции для babel-loader:
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('examples'), resolve('test'), resolve('packages')]
}
Таким образом, мы создали простую структуру каталогов.
Далее нам нужно подумать о том, как писать документацию. Для написания документов, естественно, больше всего подходит уценка, так как же мы можем писать документы уценки под vue? Ответ, конечноvue-markdown-loader. Затем мы настроили соответствующую информацию о плагине в соответствии с документацией:
rules: [
{
test: /\.md$/,
loader: 'vue-markdown-loader'
}
]
Что ж, можно начинать пробовать писать документацию, создать новый test.md в директории example/docs.
# test
> Hello World
Также создайте новый маршрут, указывающий на наш файл md:
{
path: '/test',
name: 'test',
component: r => require.ensure([], () => r(require('../docs/test.md')))
}
откройте наш браузерhttp://localhost:8080/#/test
Ха-ха, это действительно сработало. Не слишком радуйтесь.... Проблема еще позади: мы ожидаем, что документ не только скомпилирует markdown, но и лучше распознает демо-блок кода с одной стороны для демонстрации, с другой стороны, лучше всего отобразите демонстрационный код, например:
Итак, что нам нужно сделать? vue-mark-down определенно больше, чем это! Поэтому мы продолжили читать его документацию и обнаружили, что он на самом деле инкапсулируетmarkdown-it, который поддерживает опцию options. Таким образом, мы можем определить уникальные идентификаторы для нашей уценки, здесь я использую demo Определяет, где должен отображаться блок кода, поэтому мне нужно настроить параметр параметров:
const vueMarkdown = {
preprocess: (MarkdownIt, source) => {
MarkdownIt.renderer.rules.table_open = function () {
return '<table class="table">'
}
MarkdownIt.renderer.rules.fence = utils.wrapCustomClass(MarkdownIt.renderer.rules.fence)
return source
},
use: [
[MarkdownItContainer, 'demo', {
// 用于校验包含demo的代码块
validate: params => params.trim().match(/^demo\s*(.*)$/),
render: function(tokens, idx) {
var m = tokens[idx].info.trim().match(/^demo\s*(.*)$/);
if (tokens[idx].nesting === 1) {
var desc = tokens[idx + 2].content;
// 编译成html
const html = utils.convertHtml(striptags(tokens[idx + 1].content, 'script'))
// 移除描述,防止被添加到代码块
tokens[idx + 2].children = [];
return `<demo-block>
<div slot="desc">${html}</div>
<div slot="highlight">`;
}
return '</div></demo-block>\n';
}
}]
]
}
Вот краткое описание того, что делает этот код: во-первых, скомпилировать фрагмент vue в контенте в html для отображения, а с другой стороны, использовать Highlight для выделения блока кода.demo-block
Это наш определенный компонент:
<template>
<div class="docs-demo-wrapper">
<div :style="{maxHeight: isExpand ? '700px' : '0'}" class="demo-container">
<div span="14">
<div class="docs-demo docs-demo--expand">
<div class="highlight-wrapper">
<slot name="highlight"></slot>
</div>
</div>
</div>
</div>
<span
class="docs-trans docs-demo__triangle"
@click="toggle">{{isExpand ? '隐藏代码' : '显示代码'}}</span>
</div>
</template>
Таким образом, наш test.md можно записать так:
2. Как писать компоненты
Окружение готово, и тогда мы начнем писать компоненты, учитывая библиотеку компонентов, чтобы мы могли сделать так, чтобы наши компоненты поддерживали глобальный импорт и импорт по запросу.Если глобальный импорт, то все компоненты должны быть зарегистрированы на компоненте Vue, а экспорт :
const install = function(Vue) {
if (install.installed) return;
components.map(component => Vue.component(component.name, component));
};
export default {
install
};
Затем для загрузки по требованию нам нужен только один компонент экспорта:
import Button from './button/index.js';
import Row from './row/index'
import Col from './col/index'
const components = [
Button,
Row,
Col
];
const install = function(Vue) {
if (install.installed) return;
components.map(component => Vue.component(component.name, component));
};
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue);
}
export default {
install,
Button,
Row,
Col
};
Во-вторых, нам также необходимо рассмотреть проблему: поскольку это одностраничное приложение, необходимо решить проблему конфликтов стилей, если в компоненте используется soped, то стиль не может быть извлечен из компонента, а цель настройки цвета темы не может быть достигнуто. Нам нужен набор стилей, которые могут обрабатываться отдельно, могут компилироваться сами по себе и не могут загрязнять друг друга. В настоящее время особенно важна БЭМ-спецификация css. Если вы еще не знаете, что такое ссылка БЭМ:Woohoo. Я 3 с prussian.com/CSS/CSS-arc….
Говоря об этом, текущий плагин, который лучше поддерживает спецификацию БЭМ, — это postcss, который позволяет нам настраивать коннекторы и аббревиатуры между БЭМами:
{
"browsers": ["ie > 8", "last 2 versions"],
"features": {
"bem": {
"shortcuts": {
"component": "b",
"modifier": "m",
"descendent": "e"
},
"separators": {
"descendent": "__",
"modifier": "--"
}
}
}
}
Таким образом, мы можем извлечь стили отдельно, упаковать и скомпилировать их через gulp:
gulp.task('compile', function() {
return gulp.src('./src/*.css')
.pipe(postcss([salad]))
.pipe(cssmin())
.pipe(gulp.dest('./lib'));
});
Наконец, сгенерируйте наш код стиля.
Хорошо, давайте начнем наш тест:
import VVUI from '../packages/index'
import '../packages/theme-default/lib/index.css'
Vue.use(VVUI)
Все выглядит так красиво....
Оптимизация и недостатки
- Код экспорта компонента не поддерживает автоматическую генерацию: например, наш индексный файл компонента необходимо перезаписывать каждый раз при добавлении компонента.
Вы можете попробовать конфигурацию веб-пакета,npm run dev
Когда компонент автоматически обнаруживает и помогает нам написать код для экспорта. - Дефекты в разделении структуры каталогов: В настоящее время весь контент поддерживает только китайский язык.Если вы хотите поддерживать интернационализацию, вам необходимо перенастроить структуру каталогов.
- Публикация тегов: необходимо написать сценарии для поддержки публикации тегов.
- Слишком мало компонентов:Документ только что написан, и компонентов пока не так много.Потихоньку поддерживайте его.Верю,компонентов будет все больше и больше.Также можно добавлять часто используемые компоненты в процессе ведения бизнеса,что более удобно для вашего будущего обслуживания и обучения.
Заключение:
Адрес проекта на гитхабе:github
Адрес демонстрации проекта:демо
Добро пожаловать, чтобы поддерживать PR вместе, добро пожаловать, звезда
о
Автор: обезьяна Ван
Моя домашняя страница:monkeyWang
Публичный аккаунт WeChat: время от времени будут публиковаться технические статьи о внешнем интерфейсе, пожалуйста, обратите внимание
WeChat.QQ.com/Day/Y II XQ YJ E8…(автоматическое распознавание QR-кода)