Практика мобильного помощника Vue (1) — функция создания скинов на основе Vue

Vue.js

Недавно я несколько месяцев работал над небольшой демонстрацией Vue для мобильных устройств, один из которых — реализовать унифицированную функцию оформления каждой страницы. Подумываю написать статью, чтобы написать о некоторых проблемах, возникших в процессе внедрения.

Онлайн-демонстрация проекта

Онлайн-демонстрация проекта (переключиться в режим мобильной отладки)

Адрес проекта на гитхабе

Адрес проекта на гитхабе

Давайте посмотрим на эффект

Установить цвет темы
Чтобы быть разумной, такая функция, я думаю, есть несколько моментов, которые можно сказать и реализовать пошагово:
1. Выбор значения цвета
2. Некоторые нишевые варианты использования scss (пакетная установка значений CSS с несколькими переменными)
3. Применение глобальной шины событий

1 Подбор и принцип значения цвета

Я рекомендую всем взглянуть на Ant FinancialРекомендации по дизайну, в котором есть хороший набор руководств и предложений по общему взаимодействию и дизайну интерфейса. Те, кто любит читать книги, могут также прочитать «Книги по дизайну, написанные для всех».
Для цветовых элементов в интерфейсе нам вообще нужно сохранять визуальную преемственность, то есть один и тот же набор цветов, стараться использовать значения цветов на одном и том же цветовом круге

Значения цвета на одном кольце будут выглядеть более скоординированными как набор цветов.

Итак, вот предложение дизайна муравья, возьмите определенное значение цвета столбца в качестве цвета темы нашей серии (обратитесь к его официальному веб-сайту для конкретного значения цвета ~)

В некоторых особых случаях необходимо показать разницу в цвете, напримербросить монетудва цвета страницы,

2 Преобразование значения цвета формата в шестнадцатеричное значение цвета

Здесь мы различаем разные цвета, устанавливая прозрачность цвета темы, а затем сохраняем#123456В качестве нашей темы используется шестнадцатеричная глобальная переменная цвета. Здесь нам нужно преобразовать значение цвета в таком формате в значение цвета, представленное rgba. Код выглядит следующим образом, запасной

  hexToRgba (hex, opacity = 0.3) {
    let color = []
    let rgb = []
    hex = hex.replace(/#/, '')
    for (let i = 0; i < 3; i++) {
      color[i] = '0x' + hex.substr(i * 2, 2)
      rgb.push(parseInt(Number(color[i])))
    }
    return `rgba(${rgb.join(',')},${opacity})`
  }

##3 Некоторые нишевые применения scss
В итоге мы получили такую ​​кучу цветов темы, которую хотели

$colors: #f04134, #00a854, #108ee9, #f5317f, #f56a00, #7265e6, #ffbf00, #00a2ae, #2e3238;

Очень прямая идея: нам нужно определить цвет элементов, необходимых для установки темы на каждой странице просмотра, например, цвет текста и значка, а также фон головы. Поэтому мы определяем переменную цвета в приложении и распределяем ее по каждому компоненту представления.С помощью этой глобальной переменной мы можем управлять цветом всех страниц маршрутизации для достижения различных эффектов темы.
Реализация диспетчеризации описана в следующем разделе, здесь мы сначала завершаем наш первый шаг, мы можем легко извлечь наши требования:
4 Установите и сохраните глобальный цвет
Мелочи по интерфейсу:
Эту функцию я реализовал прямо на главной странице, в проекте внедрил фреймворк mint-ui (мобильный фреймворк команды Ele.me, жаль, что он не так удобен в использовании, как element.ui) , а взаимодействие настроек использует эластичный слой mt-popup.Форма хорошая, затем нажмите на цветовой блок напрямую, чтобы установить соответствующее значение цвета

 <!-- 設置顏色 -->
    <mt-popup v-model="changColor" position="bottom" class="color-panel">
      <div class="color-items">
          <span class="color-item" v-for="(item, $index) in colors"  :key="$index" @click="chooseColor(item)">
            <span class="color-cycle" :class="'bg-color' + ($index + 1)"></span>
            </span>
      </div>
    </mt-popup>

Затем идет презентация блока цветов div.Из вышеприведенного кода я могу легко увидеть таблицу стилей css, подобную этой

.bg-color1 {background: #f04134}
.bg-color2 {background: #f04134}
.bg-color3 {background: #f04134}
.bg-color4 {background: #f04134}
···

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

// mixin.scss:
$colors: #f04134, #00a854, #108ee9, #f5317f, #f56a00, #7265e6, #ffbf00, #00a2ae, #2e3238;

// setColor.vue:
@import '~@/assets/mixin.scss';
···
@for $i from 1 to 10 {
        .bg-color#{$i} {
          background-color: nth($colors, $i)
        }
      }

В дополнение к обычно используемому вложенному написанию имен классов, scss имеет много сдержанных и роскошных синтаксисов. цикл, когда надо писать Когда стиль вводится как переменная, а при написании стиля использовать цикл sass для обращения к соответствующему значению, чтобы как бы не расширялся и не менялся стиль установки цвета, он хорошо, чтобы стать цветной границей фона, мне нужно только поддерживать миксин Значение цвета в файле достаточно. Та же практика также может быть применена к унификации размера шрифта и значения интервала в проекте. Короче говоря, давайте попробуем испытать это.

5 мелочей логики

В этом проекте localstorage в основном используется в качестве базы данных, поэтому, когда вы нажимаете на цветовой блок, чтобы установить тему, мы делаем вид, что делаем запрос и сохраняем измененный цвет в localstorage ( ./static/api.json — это json который возвращает helloword, чтобы здесь использовался реализм, шина событий $bus говорит ниже, функция состоит в том, чтобы установить глобальную переменную цвета темы, localStorage имитирует, что мы сохраняем настройки в фоновом режиме и получаем эти настройки каждый раз, когда страница снова открыт), пока что наши настройки Страница почти завершена

// 假装调用接口设置颜色
    chooseColor (color) {
      this.$axios.get('./static/api.json')
        .then((data) => {
          this.$bus.$emit('set-theme', color)
          this.changColor = false
          localStorage.setItem('themeColor', color)
        })
        .catch((data) => {
          console.log(data)
        })
    }

6 Использование шины событий

В конце предыдущего шага у нас есть ключевая вещь, которая не была завершена,this.$bus.$emit('set-theme', color), установить выбранный цвет на глобальный, структура моего кода такая

子组件
Подсборка

<setColor>даhome 页面Дочерний компонент , и, как мы сказали в начале, мы хотим определить переменную цвета в нашем app.vue (home.vue и других родительских компонентах представления) и распространить ее на каждый компонент представления. Так что это на самом делеsetColorвызыватьapp.vueДля события set color дочерний компонент связывается с родительским компонентом.

Мы можем использовать события связывания для прямой координацииemit()практика, вapp.vueопределитьsetglobalColorметод и привязать его к router-view (включая home.vue), а затем продолжить определение домашнего компонентаsetglobalColorреализована функция emit('setglobalColor') для запуска метода app.vue и поместитьhome.vueэтоsetglobalColorПродолжайте привязку к компоненту.Когда вы нажимаете на цвет в компоненте, вы можете напрямую испускать этот метод.
Почему я хочу использовать шину событийШина событий .vue и vuex всегда осторожны в руках некоторых начинающих программистов, и я такой же, потому что как нечто, затрагивающее общую ситуацию, я обычно чувствую, что мне это не нужно, а код можно упростить. Мы часто используем одно слово, не рекомендуется.
Но однажды я часто задаюсь вопросом, что важнее производительности и «риска» с точки зрения читабельности кода и удобства сопровождения. Основная проблема с глобальными решениями, такими как шина событий и vuex, заключается в том, что они являются глобальными, что может вызвать конфликты из-за одного и того же имени события и имени переменной, а также вызвать избыточность и дополнительные накладные расходы в небольших проектах. Но на самом деле мы можем стандартизировать именование событий и переменных по соглашению, а с точки зрения производительности, используя шину событий и проекты vuex, с точки зрения производительности и прямогоpropsПо сравнению с проектами, которые передают данные и генерируют callback-события, особой разницы нет, но она бесконечна.props 和 emit, создавая ощущение хлопотности и сложности в обслуживании. как вышеsetglobalColor, просто охватывающий два слоя компонентов, процесс становится громоздким. Поэтому я предлагаю вам сделать это в проектах с более чем двумя уровнями компонентов и немного большим потоком данных, а также определить глобальную шину событий.

export default (Vue) => {
  let eventHub = new Vue()
  Vue.prototype.$bus = {
    $on (...arg) {
      eventHub.$on(...arg)
    },
    $off (...arg) {
      eventHub.$off(...arg)
    },
    $emit (...arg) {
      eventHub.$emit(...arg)
    }
  }
}

Чтобы привязать шину событий к текущему объекту vue, вам нужно всего лишь:

this.$bus.$on('set-theme', (color) => {··· })
this.$bus.$emit('set-theme', '#000000')

В этой демонстрации я привязываюсь к app.vue

this.$bus.$on('set-theme', (color) => {
      this.loadingColor = color
      this.userinfo.color = color
    })

пока вsetColor.vueОн срабатывает при нажатии на цветовой блокthis.$bus.$emit('set-theme', color),Затем мы можем добиться эффекта установки глобального цвета. Преимущество этого в том, что для связи между несколькими уровнями или родственными компонентами нам больше не нужны слишком громоздкие реквизиты, например, я также привязал их в header.vue.this.$bus.$on('set-theme', (color) => { }),существуетthis.$bus.$emitКогда это происходит, цвет фона заголовка можно изменить напрямую, не дожидаясь, пока app.vue передаст свойства глобального значения цвета в header.vue (например, только здесьheader.vueТолькоapp.vueСледующий уровень потока данных через реквизит будет понятнее)
И для других компонентов маршрутизируемой страницы, иapp.vueВсе они являются прямыми подчиненными и подчиненными отношениями.Мы по-прежнему используем реквизиты для поддержания четкого потока данных вниз.demoЯ будуcolorЕсть информация о пользователе (в будущем будут и другие данные), информация о пользователе передается каждому подмаршруту, и, наконец, при создании каждой страницы хорошо получить глобальный цвет, а затем использовать dom для изменения соответствующего стиля, Например

mounted () {
    this.$nextTick(() => {
      // 绑定设置主题的事件,一旦触发修改主题,则将当前字体颜色改为对应颜色
      this.$el.querySelector('.myTitle').style.color = this.userinfo.color
      this.$el.querySelector('.weui-btn_primary').style.backgroundColor = this.userinfo.color
      this.$el.querySelector('.add_icon').style.color = this.userinfo.color
    })
  }

Для подробной реализации, пожалуйста, обратитесь к коду проекта. Здесь я выберу только некоторые из наиболее очевидных моментов для обсуждения. Некоторые спецификации и привычки проекта и кода по-прежнему очень важны. Я надеюсь, что есть хорошие практики, на которых можно поучиться. друг друга и добиться прогресса~

Я KimyAndKath, надеюсь поделиться хорошими вещами вместе.

Онлайн-демонстрация проекта

Онлайн-демонстрация проекта (переключиться в режим мобильной отладки)

Адрес проекта на гитхабе

Адрес проекта на гитхабе