Нетрадиционный — VUE реализует переключение тем для определенных сценариев.

JavaScript Vue.js
Нетрадиционный — VUE реализует переключение тем для определенных сценариев.

Автор: Лю Вэньтао

Исходное заявление: Эта статья подготовлена ​​членами команды интерфейса чтения YFE, пожалуйста, уважайте оригинальность, пожалуйста, свяжитесь с общедоступной учетной записью (id: yuewen_YFE) для авторизации и укажите автора, источник и ссылку.

Существует несколько распространенных схем реализации переключения скинов страниц: замена ссылок css, замена className, изменение значений нативных переменных css, использование less.modifyVars, доставка параметров props и т. д.; В разных бизнес-сценариях мы обычно выбираем разные методы для достижения наших целей. Недавно при реализации функции тем на платформе операционной деятельности компании мы опробовали новое решение для реализации переключения тем страниц.Цель - улучшить ремонтопригодность и масштабируемость проекта и снизить сложность доступа.

Требования к теме

Прежде чем понять функцию темы, давайте сначала решим бизнес-сценарий:На фоне действия операции отредактируйте страницу конфигурации действия, перетащите мышью, чтобы выбрать нужный соответствующийкомпоненты, и установите соответствующие элементы конфигурации компонента, нажмите «Сохранить», после завершения действия по публикации страницы действия стойка регистрации может получить доступ к соответствующему действию генерации. Страница редактирования выглядит следующим образом:

Исходя из вышеизложенного, наше требование таково: на странице конфигурации фона операции для реализации функции глобального переключения темы особые требования заключаются в следующем:

  1. На странице конфигурации при инициализации страницы тема может переключать стили всех компонентов одним щелчком мыши;
  2. Конфигурация компонентов на странице может настроить соответствующий стиль компонента для переопределения стиля темы;
  3. Нажмите «Установить тему» ​​еще раз, чтобы переопределить стиль компонента, которому был присвоен стиль;

Эффект реализации показан на следующем рисунке:

После понимания требований к проекту 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
}

Наконец реализован эффект финального переключения темы.

Преимущества, которые дает этот метод:

  1. В коде компонента почти нет навязчивости, компоненту нужно только изменить параметры, связанные со стилем, с помощью специальных меток, а правила относительно просты;
  2. Параметры не нужно выдавать слой за слоем, что легко поддерживать;
  3. Тема относительно независима от основной функции, ее можно легко удалить, и проект может нормально работать;

Суммировать

Реализация темы, будь то обычный способ или реализация темы в вышеуказанных проектах, часто требует понимания бизнес-характеристик, чтобы найти наиболее подходящее решение. Разные проекты имеют разные методы реализации, но цель состоит в том, чтобы улучшить ремонтопригодность и масштабируемость проекта, а также уменьшить сложность доступа.

Текущий план реализации проекта по-прежнему является хорошим решением, или его можно использовать в качестве новой идеи для ознакомления.

Чтобы узнать больше, подпишитесь на YFE:

Чтобы узнать больше о команде, заглянитеОфициальный сайто 😄