Автор: Лю Вэньтао
Исходное заявление: Эта статья подготовлена членами команды интерфейса чтения YFE, пожалуйста, уважайте оригинальность, пожалуйста, свяжитесь с общедоступной учетной записью (id: yuewen_YFE) для авторизации и укажите автора, источник и ссылку.
Существует несколько распространенных схем реализации переключения скинов страниц: замена ссылок css, замена className, изменение значений нативных переменных css, использование less.modifyVars, доставка параметров props и т. д.; В разных бизнес-сценариях мы обычно выбираем разные методы для достижения наших целей. Недавно при реализации функции тем на платформе операционной деятельности компании мы опробовали новое решение для реализации переключения тем страниц.Цель - улучшить ремонтопригодность и масштабируемость проекта и снизить сложность доступа.
Требования к теме
Прежде чем понять функцию темы, давайте сначала решим бизнес-сценарий:На фоне действия операции отредактируйте страницу конфигурации действия, перетащите мышью, чтобы выбрать нужный соответствующийкомпоненты, и установите соответствующие элементы конфигурации компонента, нажмите «Сохранить», после завершения действия по публикации страницы действия стойка регистрации может получить доступ к соответствующему действию генерации. Страница редактирования выглядит следующим образом:
Исходя из вышеизложенного, наше требование таково: на странице конфигурации фона операции для реализации функции глобального переключения темы особые требования заключаются в следующем:
- На странице конфигурации при инициализации страницы тема может переключать стили всех компонентов одним щелчком мыши;
- Конфигурация компонентов на странице может настроить соответствующий стиль компонента для переопределения стиля темы;
- Нажмите «Установить тему» еще раз, чтобы переопределить стиль компонента, которому был присвоен стиль;
Эффект реализации показан на следующем рисунке:
После понимания требований к проекту VUE для реализации функции темы, общий способ думать об этом — отправить параметр темы через реквизиты. Тогда давайте сначала поговорим об обычном методе реализации: методе реализации доставки реквизита.
нормальная реализация
Определите тему
Во-первых, я определяю theme.js как параметры, связанные с темой, следующим образом:
const DEFAULT_THEME = {
primary: '#2F54EB',
subPrimary: '#D6E4FF',
error: '#F5222D',
success: '#52C41A',
warning: '#FAAD14',
background: '#FFFFFF',
text: '#222222'
}
export default {
DEFAULT: DEFAULT_THEME,
FIRST: {
...DEFAULT_THEME,
background: '#2590ff'
}
}
Основной модуль доставляет тему в компонент
Затем в основном модуле необходимо передать компоненту параметр темы и параметры конфигурации, связанные с компонентом, нажать кнопку для переключения темы:
<template>
<div>
<div @click="changeTheme">换主题</div>
<Component
v-for="(item, index) in componentList"
:theme="theme"
:key="index"
...item.config // 业务相关参数都在config中
/>
</div>
</template>
<script>
import theme from 'theme.js'
export default {
name: "themeChange",
data() {
return {
theme: theme['DEFAULT']
}
},
methods: {
changeTheme() {
this.theme = theme['FIRST']
}
}
}
</script>
Компонент слушает тему, чтобы изменить стиль компонента
В компоненте получите параметры конфигурации и параметры темы, переданные вышестоящим компонентом, и отслеживайте изменение темы.Когда есть изменение, сбросьте значение параметра стиля на стиль темы:
<template>
<div>
<div :style="{ background: config.bgColor }">主题</div>
</div>
</template>
<script>
import theme from 'theme.js'
const initTheme = theme['DEFAULT']
export default {
name: "themeSwitch",
props: {
theme: {
type: Object,
default: () => ({})
},
bgColor: {
type: String,
default: initTheme.background
},
...
},
data() {
return {
config: {
bgColor: this.bgColor,
...
}
}
},
watch: {
'theme' (to, from) {
this.config.bgColor = this.theme.bgColor
}
}
}
</script>
Увидев это, все скажут, а зачем нужно следить за изменением темы в часах, вместо того, чтобы напрямую указывать параметр, соответствующий теме, при инициализации компонента?
Поскольку то, что сказано в требованиях темы, стили, связанные с компонентом, также могут быть изменены в компоненте.Параметр bgColor в приведенном выше демонстрационном коде можно установить, щелкнув, чтобы переключить тему, или он может быть установлен самим компонентом. Источников несколько (здесь Реализация конфигурации компонента подробно раскрываться не буду); для установки темы стиль компонента установит соответствующий цвет темы, нужно следить за изменением параметра темы в часах , если происходит изменение, сбросьте соответствующий параметр, но таким образом каждый компонент должен иметь один и тот же фрагмент кода и параметры мониторинга для достижения нашего эффекта, а код очень избыточен.
Подводя итог, мы еще больше оптимизировали код и единообразно инкапсулировали метод мониторинга параметра темы, здесь будет еще одна проблема:Параметры соответствующего цвета каждого компонента неразрешимы, и уровень параметров тоже неразрешим, почти каждый компонент должен поддерживать весь массив переменных. Определенные таким образом правила могут быть относительно сложными, дорогими в обслуживании и подверженными ошибкам.
Очевидно, что такой метод реализации не очень хорош, так как же его реализовать?
«Нетрадиционная» реализация
Попробовав вышеописанный метод, мне интересно, правильно ли я думаю и если есть проблема с углом врезки, то давайте врезать под другим углом.
Начните с параметров конфигурации
Когда яOниКогда я обнаружил, что весь параметр this.componentList страницы (в котором хранится соответствующая конфигурация всех компонентов) я могу получить, яOниМожно ли начать с данных?ок, когда дело доходит до этого, идея на самом деле появляется, правила параметра в this.componentList:
[
{
componentName: 'xx',
config: {
color: 'xxx',
background: 'xxx',
...
}
},
...
]
Мы обнаружим, что при разработке компонента параметры, связанные с цветом, уже извлечены в конфигурацию, а это означает, что если я изменю значение параметра конфигурации, я действительно смогу добиться эффекта настройки темы? Потому что параметры конфигурации всех компонентов выдаются параметром this.componentList.
Параметрам присваиваются специальные идентификаторы
Определяем релевантные параметры theme.js, которые согласуются с вышеизложенным, поэтому больше говорить не буду.Главное, что в компоненте модифицируем релевантные параметры и меняем их на параметры со специальными метками, следующим образом:
<template>
<div>
<div :style="{ background: this['bgColor.t.background']}">主题</div>
</div>
</template>
<script>
import theme from 'theme.js'
const initTheme = theme['DEFAULT']
export default {
name: "themeSwitch",
props: {
'bgColor.t.background': { // .t.: 为特殊标识 ;background: 为主题里面对应的字段名 background: '#FFFFFF'
type: String,
default: initTheme.background
}
}
}
</script>
Параметры обхода для замены специальных значений параметров идентификации
При нажатии переключателя темы он будет проходить через параметр this.componentList и изменять параметр со специальной отметкой на параметр, соответствующий новой теме.Код выглядит следующим образом:
/*
* 根据主题重制componentsConfig
* @method changeTheme
* */
changeTheme () {
this.theme = theme['FIRST']
this.componentList.forEach(component => {
this._setThemeChangeConfig(component.config || {})
})
},
_setThemeChangeConfig (obj) {
Object.keys(obj).map(name => {
if (Object.prototype.toString.call(obj[name]) === '[object Object]') {
this._setThemeChangeConfig(obj[name])
} else {
const themeColorArr = name.match(/\.t\.(\S*)/)
if (themeColorArr && this.isThemeColorName(themeColorArr[1])) {
this.$set(obj, name, this.theme[themeColorArr[1]])
}
}
})
},
/*
* 判断颜色name是否在主题里面
* @method isThemeColorName
* */
isThemeColorName (name) {
let has = false
Object.keys(this.theme).forEach((paramsName) => {
if (paramsName === name) has = true
})
return has
}
Наконец реализован эффект финального переключения темы.
Преимущества, которые дает этот метод:
- В коде компонента почти нет навязчивости, компоненту нужно только изменить параметры, связанные со стилем, с помощью специальных меток, а правила относительно просты;
- Параметры не нужно выдавать слой за слоем, что легко поддерживать;
- Тема относительно независима от основной функции, ее можно легко удалить, и проект может нормально работать;
Суммировать
Реализация темы, будь то обычный способ или реализация темы в вышеуказанных проектах, часто требует понимания бизнес-характеристик, чтобы найти наиболее подходящее решение. Разные проекты имеют разные методы реализации, но цель состоит в том, чтобы улучшить ремонтопригодность и масштабируемость проекта, а также уменьшить сложность доступа.
Текущий план реализации проекта по-прежнему является хорошим решением, или его можно использовать в качестве новой идеи для ознакомления.