Использование VueJS для разработки приложений нельзя отделить от процесса разделения модулей между приложениями и разборки больших интерфейсов на компоненты, мы можем легко использовать его в одном файле<template>Блок поддерживает вид компонента, используя<script>Чтобы сохранить логическую часть компонента, используйте<style>Сохраняйте стили для компонентов.
Когда мы стилизуем компоненты VueJS, одну вещь нельзя игнорировать — загрязнение стиля.
Причины загрязнения стиля
Упоминания о загрязнении стиля, в основном восходящие кWebpackправильноCSSПроцесс упаковки файла, здесь мы используемVue-Element-AdminПримеры элементов конфигурации Webpack в:
const webpackConfig = merge(baseWebpackConfig, {
plugins: [
new MiniCssExtractPlugin({
filename: utils.assetsPath('css/[name].[contenthash:8].css'),
chunkFilename: utils.assetsPath('css/[name].[contenthash:8].css')
}),
]
})
Webpack используетMiniCssExtractPluginПлагин, который разделяет код CSS в файле (например, однофайловый компонент Vue) в форму, подобную однофайловому компоненту Vue, после обработкиapp.hash1234.cssОтдельный файл CSS для:
Если в проекте имеется большое количество ClassNames с одинаковыми именами без добавления мер по предотвращению загрязнения стиля, могут возникнуть неожиданные переопределения веса селектора CSS.Это может привести к тому, что классы с более высоким весом селектора в определенных частях более позднего файла повлияют на весь Приложение, и этот процесс обычно происходит при написании компонентов, поэтому его обычно называют загрязнением стиля компонента.
Webpack & Vue SFC Object
Для проектов Vue использование Webpack значительно оптимизирует рабочий процесс, поскольку черезVue Loader, однофайловые компоненты Vue можно хорошо интегрировать в рабочий процесс Webpack.
Отслеживая исходный код, можно обнаружить, что написанные нами однофайловые компоненты обрабатываются какSFC对象, То есть, включающий один HTML-модуль, один модуль сценария, один или несколько модулей стилей, пользовательских модулей один или несколько объектов:
// vue-loader/index.js
const descriptor = parse({
source,
compiler: options.compiler || loadTemplateCompiler(),
filename,
sourceRoot,
needMap: sourceMap
})
// vuejs/component-compiler-utils/index.js
function parse(options) {
const { compiler } = options
output = compiler.parseComponent(source, compilerParseOptions)
return output
}
// vue.js
function parseComponent(content, options) {
// ...
var sfc = {
template: null,
script: null,
styles: [],
customBlocks: []
}
// ...
return sfc
}
Мы можем быть интегрированы в структуру SFCWebpackВ процессе разработки в основном наблюдаются следующие эффекты:
- Позволяет использовать другие загрузчики веб-пакетов для каждой части компонентов Vue, например, в
<style>Часть использует Sass Loader, в<customBlocks>Деталь использует пользовательский загрузчик - Использование загрузчика webpack
<style>а также<template>Ресурсы, на которые есть ссылки, рассматриваются как зависимости модуля. - CSS с имитацией области действия
- Используйте горячую перезагрузку для сохранения состояния во время разработки
Следующее основное введениеScoped CSSпринцип.
Scoped CSS
Принцип Scoped CSS в просторечной версии
Вызовите соответствующий загрузчик в VueJS через Webpack, чтобы добавить настраиваемые атрибуты в HTML-шаблон компонента.data-v-xи добавьте соответствующий селектор атрибутов в селектор CSS в компоненте (селектор атрибутов).[data-v-x], так что стиль в компоненте может действовать только с HTML в компоненте. Эффект кода выглядит следующим образом:
<div class='lionad' data-v-lionad></div>
<style>
.lionad[data-v-lionad] {
background: @tiger-orange;
}
</style>
отслеживание источника
Прежде чем Webpack будет использовать другие загрузчики CSS для обработки соответствующего кода CSS в VueJS,Vue LoaderДля нас сделан простой слой обработки, если компонентstyleблок содержитscopedАтрибуты:
<!-- 某个VueJS组件中 -->
<template>
<div class='lionad'></div>
</template>
<style lang="scss" scoped>
.lionad {
background: @tiger-orange;
}
</style>
Следующий код судит текущееSFCтам в блоке стиля объектаscopedатрибут, и вставьте его в запрос.Кстати, после разбора каждого однофайлового компонента будет сгенерирован соответствующий идентификатор компонента.Идентификатор в основном различается средой производства/разработки, а значение пути к файлу + исходный код или путь к файлу используется в качестве собственного значения хэша, генерируемого в виде:
// vue-loader/index.js
const id = hash(isProduction (shortFilePath + '\n' + source) : shortFilePath)
const hasScoped = descriptor.styles.some(s => s.scoped)
const query = `? vue&type=template${idQuery}${scopedQuery}`
const request = templateRequest = stringifyRequest(src + query)
templateImport = `import { render, staticRenderFns } from ${request}`
Обработка HTML-шаблонов
Используется для обработки шаблонов HTML в структурах SFC.templateLoader, мы можем знать, что параметры, заданные в запросе, будут объединены в параметры загрузчика и перенаправлены через Webpack.templateLoaderретранслировать@vue/component-compiler-utils.compileTemplateиметь дело с:
// vue-loader/templateLoader.js
const query = qs.parse(this.resourceQuery)
const { id } = query
const compilerOptions = Object.assign({}, options.compilerOptions, {
scopeId: query.scoped ? `data-v-${id}` : null
})
const compiled = compileTemplate({ compilerOptions })
действительныйcompileTemplateКогда функция обрабатывает содержимое, функция компиляции использует компилятор в запросе илиvue-template-compiler, который преобразует текст шаблона в функцию рендеринга JavaScript примерно следующим образом:
- Преобразование из шаблона HTML в AST (виртуальное синтаксическое дерево)
- Оптимизация AST, обработка статических шаблонов и динамических шаблонов
- Создание функций JS для создания простого HTML во время выполнения.
Коды соответствуют:
// vue-template-compiler/build.js/createCompilerCreator
var ast = parse(template.trim(), options)
optimize(ast, options)
var code = generate(ast, options)
Ранее идентификатор нашего компонента помещался во внутреннюю структуру данных, когда начальный тег анализировался на этапе анализа:
function elementToOpenTagSegments (el, state) {
var segments = [{ type: RAW, value: ("<" + (el.tag)) }]
// _scopedId
if (state.options.scopeId) {
segments.push({ type: RAW, value: (" " + (state.options.scopeId)) })
}
segments.push({ type: RAW, value: ">" })
return segments
}
Ранее наш HTML-шаблон<div class='lionad'></div>Начальный тег будет преобразован в следующую структуру данных:
[
{ type: RAW, value: '<div' },
{ type: RAW, value: 'class=lionad' },
{ type: RAW, value: 'data-v-xxxxxx' },
{ type: RAW, value: '>' },
]
работа с шаблоном стиля
Подобно процессу разбора шаблонов HTML, шаблоны стилей передаются через Webpack.stylePostLoaderДля обработки логика обработки в основном относится к@vue/component-compiler-utilsсерединаcompileStyleраздел, последний представит плагины к шаблонам с тегами области во время процесса анализа шаблонов стилей.stylePlugins/scoped.js, scoped.jsБудуdata-v-xxxxxxПроцесс добавления в конец селектора выглядит следующим образом:
selectors.each((selector) => {
selector.each((n) => {
if (n.value === '::v-deep' || n.value === '>>>' || n.value === '/deep/') {
return false;
}
});
selector.insertAfter(node, selectorParser.attribute({
attribute: id
}))
})
Отступление, по приведенному выше коду мы обнаружили, что когда в настоящее время обрабатываются три конкретных типа селекторов, цикл будет завершен, а остановка будетdata-v-xxxДобавьте в конец селектора:
- псевдокласс
::v-deep - Селектор
>>> - Селектор
/deep/
Мы можем использовать эту возможность для записи проникновения стиля в компоненты, то есть внутренние компоненты влияют на стили внешних компонентов (ε=ε=ε=┏(゜ロ゜;)┛ Активное загрязнение стиля), конечно, это полезно в конкретных ситуациях Например, когда мы хотим активно переопределять стили сторонних фреймворков компонентов пользовательского интерфейса, но не хотим вводить новые файлы CSS или не хотим писать шаблоны CSS без области действия.
наконец
Мне нужно побеспокоиться о передних блюдах, а текст не подробный или неправильный. Добро пожаловать в большие ребята. Если эта статья была вам полезна, было бы здорово. Видеть это все настоящая любовь (смеется.jpg) Беда点赞 收藏 关注 三连击!!!
Чтобы облегчить понимание или не вдаваться в неприятные подробности, фрагменты исходного кода в тексте были частично удалены.