При разработке MVP (минимально жизнеспособного продукта) вы намереваетесь как можно быстрее перейти от идеи к прототипу. Чем быстрее вы сможете прототипировать свою идею, тем быстрее вы сможете ее повторить.

Когда вы переходите от абстрактной идеи к рабочему прототипу, вы обычно не хотите тратить много времени на создание нестандартного дизайна, когда вам следует сосредоточиться на функциональности приложения. Чтобы решить эту проблему, мы используем такие фреймворки, как Bootstrap, для быстрого создания структурированного макета с пользовательским интерфейсом, который выглядит «довольно хорошо» без особых усилий.

Что мы действительно хотим достичь с точки зрения дизайна, так это быстро создать пользовательский интерфейс, который будет узнаваемым и согласованным.

Я собираюсь показать вам супербыстрый способ перехода от абстрактной идеи к дизайну и созданию рабочего прототипа с помощью Material Design. Material Design - это дизайнерская система Google с открытым исходным кодом, которую они используют во всех своих приложениях. Это делает его узнаваемым, потому что он интуитивно понятен и прост в навигации, и большинство людей уже знакомы с ним. Если вы еще этого не сделали, вам обязательно стоит узнать, что такое Материальный дизайн.

Используя подключаемый модуль Material Design для Sketch, мы создадим нашу собственную настраиваемую систему Material Design. Это будет включать в себя отличный набор компонентов, которые позволят нам быстро создавать согласованные проекты для нашего прототипа приложения. Мы сделаем простое приложение для напоминаний.

Мы будем использовать интерфейсный фреймворк Vue.js вместе с библиотекой компонентов материального дизайна Vuetify.js для реализации дизайна наших приложений. Давайте приступим к делу!

Создание дизайн-системы

Загрузите этот плагин для Sketch. После установки просто перейдите в раздел Плагины ›Материал› Открыть редактор тем, чтобы увидеть редактор тем оформления материалов. Нажмите Создать новую тему, и мы решили начать с базовой темы.

Теперь нам представлена ​​наша система Material Design, состоящая из компонентов Sketch.

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

Мы создали нашу дизайн-систему. Как видите, там написано, что документ является библиотекой. Это означает, что любые изменения, которые вы вносите в этот файл Sketch, повлияют на ваши макеты и обновят все ваши проекты с этими изменениями. Насколько это здорово?

Прежде чем продолжить, мы также установим плагин Sketch Material, который добавит некоторые модули, которые мы скоро будем использовать.

Мокапы

Давайте начнем с открытия нового документа Sketch, затем создадим новую монтажную область iPhone и сохраним его как MaterialReminders.sketch. Здесь мы будем создавать дизайн для нашего приложения. Но сначала давайте исследуем богатую библиотеку компонентов, которая находится в нашем распоряжении.

В разделе Вставка ›Символы вы должны увидеть только что созданную библиотеку компонентов.

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

  • Добавить новое напоминание
  • Удалить напоминание
  • Отметьте напоминание из вашего списка дел
  • Снимите отметку с напоминания в вашем заполненном списке

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

Начнем с верхней панели навигации. Бросьте его и поместите, а затем установите размер по размеру экрана. Нам нужно изменить первый значок на «Значок / Добавить / Залить» для значка меню и изменить цвет значка на белый. Затем измените все остальные значки на «Нет», так как они нам не понадобятся. Мы также меняем заголовок на Напоминания.

Теперь мы начнем добавлять фиктивные напоминания. Напоминания мы создадим в виде списка, так что давайте найдем подходящий компонент. Мы будем использовать «Список / Одна строка / Отступ / Тело 2».

Теперь мы центрируем объект списка, убираем нижний разделитель, устанавливаем текст на «Работы» и, наконец, меняем значок на «Значок / отмеченный круг / контур».

Добавьте заголовок, вставив текстовое поле, а затем с помощью модуля Плагины ›Материал эскиза› Типографика измените стиль на Подзаголовок.

Пока все выглядит неплохо! Но теперь мы столкнулись с проблемой. Мы также хотим включить элементы управления списком справа в каждый объект списка, потому что мы хотим добавить туда кнопку удаления. Но разработчики из Google не включили в компонент Sketch никакого переопределения для этого. Не беспокойтесь, мы исправим это, зайдя в файл нашей библиотеки и добавив наш значок к символу, таким образом обновляя его на протяжении всего проекта.

Перейдите в библиотеку и найдите компонент списка, который мы использовали на странице компонентов материала. Затем дважды щелкните по нему, чтобы перейти к его символу. Щелкните значок слева, чтобы он оказался в фокусе, затем скопируйте и вставьте и переместите его вправо. Сделка сделана.

Когда мы снова переключаемся на наш проект, мы видим, что в правом верхнем углу написано «Доступны обновления библиотеки».

Теперь у нас должна быть возможность изменить значок правой руки на «Значок / Закрыть / Заполнено», который будет кнопкой для полного удаления напоминания из списка.

Чтобы создать список напоминаний, мы просто копируем и вставляем еще несколько объектов списка, меняем их текст, а затем меняем заголовок, который мы добавили в Todo.

Затем мы копируем и вставляем весь этот список, чтобы создать завершенный список. В этом новом списке вы должны изменить заголовок на «Завершено», а затем изменить все значки слева, чтобы они были заполнены, а не обведены.

Мы почти закончили с нашими макетами. Чтобы ускорить процесс, я просто изменил цвет нашей монтажной области на #FAFAFA и добавил «Shadow / 00dp» позади каждого из моих списков.

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

Мы начинаем с копирования и вставки артборда, над которым мы работали, чтобы создать точную копию. Затем мы используем модули Dialogue и Form в разделе «Plugins / Sketch Material», чтобы создать диалог и форму отдельно. Затем они объединяются, и за ними помещается непрозрачный ящик. Я заменил прозрачную кнопку действия в диалоге кнопкой основного цвета.

Теперь мы закончили со Sketch. Конечно, мы могли бы добавить больше функций и еще больше расширить наши макеты, но пока мы будем простыми. Следующим шагом будет написание кода, который станет нашим приложением!

Vue с Vuetify

Теперь самое интересное - кодирование. Мы будем использовать Vue.js, который представляет собой интерфейсную библиотеку пользовательского интерфейса, написанную на JavaScript. Этому действительно легко научиться, и проверка их веб-сайта будет первым шагом. Для реализации Material Design мы будем использовать библиотеку компонентов Vuetify.js, которая включает в себя набор компонентов Vue вместе с сеткой, чтобы упростить организацию вашего макета.

Начнем с того, что просто скопируем и вставим пример разметки на стартовой странице Vuetify. Давайте посмотрим, что это для нас делает.

Когда вы смотрите на HTML, начните с внешней стороны и двигайтесь внутрь.

У нас есть теги <head></head ›и <body></body>. Внутри тега <head></head> есть теги <link>, которые извлекают необходимый vuetify.min.css файл и шрифты Google.

В <body></body> у нас есть <div></div>, а внутри у нас есть некоторые компоненты Vuetify, например <v-app></v-app> и <v-content></v-content>, которые обозначены буквой «v-» в их именах.

Далее у вас есть два тега <script></script>, которые импортируют модули Vue.js и Vuetify.js на нашу страницу.

Наконец, после операторов импорта есть третий тег <script></script>, который создает новый экземпляр Vue(). Здесь мы напишем весь наш код JavaScript.

Мы видим, что экземпляр подключается к ‘#app’, который является идентификатором тега <div></div> в нашем HTML. Это позволяет нашему экземпляру Vue знать, куда внедрить наш пользовательский интерфейс.

Внутри тега <v-content></v-content> мы скоро разместим все наши компоненты Vuetify. Но сначала мы сохраним то, что у нас есть на данный момент, как index.html, а затем откроем файл в нашем браузере, где нам должно быть представлено «Hello world».

Мы продолжаем поиск того, какой HTML нам нужен для верхнего компонента навигационной панели в документации Vuetify. Мы ищем тег <v-toolbar app></v-toolbar>. Мы также должны добавить <v-btn></v-btn> внутри этой панели навигации, чтобы мы могли нажать на нее, чтобы отобразить диалог для добавления новых напоминаний.

В этой кнопке мы также добавим событие @click=, которое установит addModal в true, что вызовет модальный диалог. Мы добавляем это между тегами <v-content></v-content>:

<v-toolbar app color="primary">
  <v-btn color="primary darken-1" icon @click="addModal = true">
    <v-icon>add</v-icon>
  </v-btn>
  <v-toolbar-title>
    Reminders
  </v-toolbar-title>
</v-toolbar>

Затем мы должны добавить HTML для диалога. Он будет находиться сразу после тега <v-toolbar-title></v-toolbar-title>, но все еще внутри тега <v-toolbar></v-toolbar>. Вот диалог:

<v-dialog v-model='addModal'>
  <v-card>
    <v-card-title>Add a reminder</v-card-title>
    <v-card-text>
      <v-container grid-list-md>
        <v-layout wrap>
          <v-flex md12>
            <v-text-field v-model="newTask" label="New task"></v-text-field>
          </v-flex>
          <v-flex md12>
            <v-btn color="primary" @click="add">Add</v-btn>
          </v-flex>
        </v-layout>
      </v-container>
    </v-card-text>
  </v-card>
</v-dialog>

Здесь мы добавляем <v-card-title> с заголовком «Добавить напоминание». Затем мы используем систему сеток Vuetify, чтобы создать список, охватывающий все 12 столбцов. Мы добавляем <v-text-field>, который привязывается к 'newTask' и имеет ярлык с надписью «Новая задача». Также будет кнопка, которая через событие @click= запускает функцию 'add', которую мы напишем через секунду.

После сохранения изменений в документе вы должны получить что-то вроде этого при обновлении страницы index.html в браузере:

Не беспокойтесь, что диалог еще не работает - сначала мы должны добавить для него функциональность в нашем Vue() экземпляре. Мы делаем это, добавляя следующее к нашему экземпляру сразу после el: '#app', но через запятую:

el: '#app',
data: {
  addModal: false,
  newTask: ''
}

В объекте data мы будем хранить состояние нашего приложения. После этой настройки наш диалог должен работать. Сохраните и обновите страницу.

Теперь всякий раз, когда вы щелкаете, чтобы открыть модальный диалог, внутреннее состояние в data: {} устанавливается на addModal: true, которое затем отображает модальное окно. Точно так же, когда вы пишете сообщение в текстовом поле диалога, оно будет сохранено в newTask, поскольку <v-text-field></v-text-field> привязано к нему через v-model=.

Теперь мы добавим код для add функции, которая сохранит все, что находится внутри newTask, в наш список напоминаний, которые скоро появятся. Эта функция должна находиться внутри объекта methods, который мы добавим после нашего объекта data: {}, в экземпляре Vue.

Функция будет выглядеть так:

add() {
  if (this.newTask !== '') {
    this.tasks.unshift({text: this.newTask, completed: false})
    this.addModal = false
    this.newTask = ''
  }
}

После включения функции в объект method: {} код должен выглядеть следующим образом:

new Vue({
  el: '#app',
  data: {
    addModal: false,
    newTask: '',  
  },
  methods: {
    add() {
      if (this.newTask !== '') {
        this.tasks.unshift({text: this.newTask, completed: false})
        this.addModal = false
        this.newTask = ''
      }
    }
  }
});

Когда срабатывает функция add(), она добавит нашу задачу из newTask в наш список еще не созданных задач, если он не пуст. Затем он закроет диалог, установив this.addModal = false, и снова установит newTask на пустой.

Давайте создадим наш список задач, чтобы мы могли начать вводить несколько напоминаний. Внутри объекта data поместите этот код:

tasks: [
   // Some dummy data
   {
    text: 'Chores',
    completed: false
   },
   {
    text: 'More chores',
    completed: false
   }
]

Это будут наши пустышки-напоминания. Как видите, у нас есть completed ключ, для которого установлено значение true или false, чтобы мы могли различать задачи, которые выполнены, и те, которые не выполнены. Это также означает, что мы не можем просто отображать наш tasks список так, как он есть в нашем пользовательском интерфейсе, потому что тогда мы будем отображать выполненные и незавершенные задачи вместе.

Мы решим эту проблему с помощью вычисленных свойств. Они работают, постоянно отслеживая изменения в вашем приложении и возвращая вычисленное значение на основе этих изменений.

Нам нужны два вычисляемых свойства: одно для списка todo и одно для списка done, каждое из которых будет разделять незавершенные и завершенные задачи. Мы добавляем computed: {} после нашего methods: {}, и добавляем вычисленные свойства todo: function() {} и done: function() {}. Функция todo вернет return this.tasks.filter(function(task) {return !task.completed}), а функция done вернет обратное, удалив ! (что означает «нет») перед task.completed. Код должен выглядеть так:

computed: {
  done: function() {
   return this.tasks.filter(function(task) {return task.completed})
  },
  todo: function() {
   return this.tasks.filter(function(task) {return !task.completed})
  }
}

Теперь мы готовы отобразить наши два списка в пользовательском интерфейсе. Это будет немного разметки, но не волнуйтесь, мы рассмотрим это вместе. Мы собираемся заменить <v-container>Hello world</v-container>, выделив его и вставив вместо него следующее:

<v-container grid-list-md>
  <v-layout row wrap>
    <v-flex xs12>
      <v-list>
        <v-subheader>Tasks to do</v-subheader>
        <v-list-tile v-for="task in todo">
          <v-list-tile-action>
            <v-btn icon ripple @click="complete(task)">
              <v-icon v-if="task.completed">check_circle</v-icon>
              <v-icon v-else>check_circle_outline</v-icon>
            </v-btn>  
          </v-list-tile-action>
          <v-list-tile-title>
            {{task.text}}
          </v-list-tile-title>
          <v-list-tile-action>
            <v-btn icon ripple @click="remove(task)">
              <v-icon color="grey lighten-1">cancel</v-icon>
            </v-btn>
          </v-list-tile-action>
        </v-list-tile>
      </v-list>
    </v-flex>
          
    <v-flex xs12>
      <v-list>
        <v-subheader>Completed tasks</v-subheader>
        <v-list-tile v-for="task in done">
          <v-list-tile-action>
            <v-btn icon ripple @click="complete(task)">
              <v-icon v-if="task.completed">check_circle</v-icon>
              <v-icon v-else>check_circle_outline</v-icon>
            </v-btn>  
          </v-list-tile-action>
          <v-list-tile-title>
            {{task.text}}
          </v-list-tile-title>
          <v-list-tile-action>
            <v-btn icon ripple @click="remove(task)">
              <v-icon color="grey lighten-1">cancel</v-icon>
            </v-btn>
          </v-list-tile-action>
        </v-list-tile>
      </v-list>
    </v-flex>
  </v-layout>
</v-container>

Для начала добавляем в наш контейнер grid-list-md. Затем мы добавляем <v-layout row wrap></v-layout> и <v-flex xs12></flex> и добавляем два наших тега <v-list></v-list> с <v-subheader></v-subheader> в каждом. Это создает наш базовый макет в виде двух списков.

Затем мы добавим <v-list-tile v-for="task in todo"></v-list-tile>, где оператор v-for= выполняет итерацию по каждому task в нашем вычисленном свойстве todo. То же самое и со свойством done. По мере того, как мы перебираем каждый список, мы будем отображать каждый элемент списка. Каждый элемент будет отображать task.text и будет иметь две кнопки: одну для запуска функции complete() и одну для запуска функции remove().

Давайте продолжим, записав их внутри нашего объекта method.

complete(task) {
  task.completed ? task.completed = false : task.completed = true
},
remove(task) {
  this.tasks = this.tasks.filter(function(x){return x !== task})
},

Тело функции complete содержит тернарный оператор, который будет переключать кнопку завершения при каждом напоминании. Всякий раз, когда task.completed установлен на true в напоминании, весь пользовательский интерфейс обновится и переместит это напоминание в список «Завершено».

Теперь у вас должен быть настоящий рабочий прототип нашего приложения для напоминаний!

Последние мысли

В этой статье я не пытался показать, как специально создать бесполезное приложение для напоминаний с ограниченной функциональностью (хотя это именно то, что я сделал). Скорее, вы можете использовать эти инструменты, которые я вам представил, чтобы очень быстро создать коллекцию макетов, а затем, с минимальной настройкой, создать настоящий рабочий прототип из этих дизайнов.

Имея это на месте, теперь вы можете настроить свою библиотеку компонентов, создать свои проекты, а затем быстро реализовать их в коде по мере продвижения.

Вы можете найти готовый файл Sketch и код здесь. Я также настоятельно рекомендую глубже изучить инструменты, о которых я говорил, чтобы полностью реализовать их потенциал.

Надеюсь, вам понравилась эта статья и вы сочтете ее полезной. Прокомментируйте, если у вас есть какие-либо вопросы, или дайте мне знать, что вы об этом думаете.