Чем вы занимаетесь: довольно длинное пошаговое руководство по созданию устройства для приготовления пиццы на Vue.js. Смысл этого в том, чтобы показать, как создавать забавные приложения с чистыми изображениями CSS и Vue.js. Если вам это нравится, вы также найдете выпущенный мной видеокурс под названием Используйте изображения на чистом CSS и Vue.js для создания забавных приложений.

Живая демонстрация: http://codepen.io/mikemang/live/9fb4d84647a0ed6cc52b987624743859

Полный код: http://codepen.io/mikemang/pen/9fb4d84647a0ed6cc52b987624743859/?editors=1010

Шаблон, которому следует следовать: http://codepen.io/mikemang/pen/c023f33ce4adb923a0fdc870ebdc9c8e

Поскольку на прошлой неделе прошел Национальный день пиццы, я решил сделать забавное приложение, которое будет использовать чистые изображения CSS и Vue.js, в котором вы можете создавать пиццу. Это приложение будет более простым, чем моя предыдущая Vue.js Pokemon Battle. Это приложение, однако, продемонстрирует некоторые интересные особенности Vue.js в сочетании с чистым CSS, которые я не охватывал в этом посте, такие как привязка классов, сокращение обработчика событий и анимация CSS.

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

Ломая это

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

  1. Разрешить пользователю выбирать различные начинки в левой части экрана.
  2. Если добавлен топпинг, необходимо обновить общую стоимость заказа.
  3. Если добавлен топпинг, он также должен появиться на пицце с правой стороны.
  4. Пользователь выберет топпинг, нажав кнопку «Да» или «Нет».
  5. После того, как пользователь введет «Да» или «Нет» для начинки, следующая опция начинки появится в левой части экрана.

Этого можно добиться, выполнив следующие действия:

  1. Создайте основной прямоугольный контейнер для приложения
  2. Иметь левый и правый контейнер, каждый из которых занимает по 50% основного контейнера.
  3. В правом контейнере добавьте изображение «полностью загруженной» (все начинки) пиццы и общую стоимость пиццы.
  4. В левом контейнере добавьте изображение в чистом виде CSS для каждого покрытия, текст для текущего покрытия и две кнопки для «Да» и «Нет».
  5. Для левого контейнера добавьте условный рендеринг, чтобы указать, какое изображение будет отображаться.
  6. Для левого контейнера обработайте ввод пользователя (да или нет) и соответствующим образом скорректируйте общую стоимость и начинки, показанные на пицце в правом контейнере. Кроме того, перейдите к следующему пункту, независимо от того, было ли введено «да» или «нет».
  7. После того, как пользователь ввел все начинки, измените класс конечной пиццы в правом контейнере, чтобы она вращалась, и измените текст в левом контейнере, чтобы спросить пользователя, хотят ли они заказать
  8. Измените текст в левом контейнере, чтобы сказать «Не в порядке», независимо от того, заказывают они пиццу или нет.

Я завершил все это, выполнив следующие действия по порядку:

  1. Создан основной прямоугольный контейнер
  2. Добавлен заголовок
  3. Создан левый и правый контейнер
  4. Создана «полностью загруженная» пицца.
  5. Создан экземпляр Vue
  6. Добавлены данные v-if для каждой начинки «полностью загруженной» пиццы.
  7. Добавлены данные о ценах на каждый топпинг, текущая цена (число), общая цена (строка) и добавлен текст общей цены в правом контейнере.
  8. Созданы кнопки "да" и "нет" и добавлены данные для текста кнопки.
  9. Создал изображение CSS для каждого покрытия и добавил данные v-if для каждого покрытия по мере их создания.
  10. Написал функцию для обработки пользовательского ввода
  11. Добавлена ​​привязка класса для добавления CSS-анимации для финальной пиццы в правом контейнере.

А теперь давайте начнем через это вместе.

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

Установите правильный контейнер

Сейчас мы должны увидеть то, что показано ниже:

Первое, что мы сделаем, это создадим наш экземпляр Vue:

JS

var app = new Vue({
  el: "#app",
  data: {
    
  },
  methods: {
    
  }
})

Здесь у нас есть новый экземпляр Vue под названием app. el of #app означает, что этот экземпляр Vue будет привязан к div с идентификатором приложения в нашем HTML, который мы можем добавить следующим образом:

HTML

<div id="app">
  <h1 class="title">Vue.js Pizza Maker</h1>
  <div class="box">
    <div class="left-container">
    </div>
    <div class="right-container">
      <div class="pizza">
        //rest of topping divs
      </div>
    </div>
  </div>
</div>

Теперь мы хотим добавить данные в наш экземпляр Vue. Первым типом данных, которые мы добавим, будут логические значения, которые мы можем использовать для управления тем, будут ли отображаться элементы div нашей «полностью загруженной» пиццы (‹div class =« pizza »›) в запуск приложения.

В начале нашего приложения мы хотим, чтобы отображался только ‹div class =« pizza »›. Позже, если пользователь добавит начальную часть с левой стороны, логическое значение будет изменено для этой начинки, и она появится. Например, если пользователь решает добавить соус, мы изменим логическое значение, управляющее рендерингом нашего ‹div class = ”auce” ›, на true, чтобы оно отображалось и соус появлялся на пицце.

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

JS

data: {
  showSauce: false,
  showWedgeCheese: false,
  showStringCheese: false,
  showPepperoni: false
}

Теперь нам нужно связать эти данные с HTML-элементами наших начинок. Мы делаем это с помощью v-if вот так:

HTML

<div class="right-container">
      <div class="pizza">
        <div v-if="showSauce" class="sauce">
        </div>
         <div v-if="showWedgeCheese" class="wedge-cheese">
          <div class="cheese-1">
          </div>
          <div class="cheese-2">
          </div>
          <div class="cheese-3">
          </div>
          </div>
          <div v-if="showStringCheese" class="string-cheese">
          </div>
        <div v-if="showPepperoni" class="pepperoni">
            <div class="pepperoni-1">
            </div>
            <div class="pepperoni-2">
            </div>
            <div class="pepperoni-3">
            </div>
          </div>
      </div>
    </div>

Теперь мы видим следующее:

Круто, правда?

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

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

JS

data: {
    showSauce: false,
    showWedgeCheese: false,
    showStringCheese: false,
    showPepperoni: false,
    currentPrice: 0,
    totalCost: "$0"
}

Как видите, мы добавили currentPrice как число (0) и totalCost как строку ($ 0). Причина, по которой мы это делаем, заключается в том, что мы можем выполнять математические операции для отслеживания текущей цены с помощью currentPrice, а затем использовать конкатенацию строк, чтобы установить totalCost как комбинацию $ + currentPrice.

А пока давайте добавим HTML-код для отображения текста для нашей totalCost в правом контейнере:

HTML

<div class="right-container">
      <div class="option"><span id="white">{{totalCost}}</span> 
      </div>
      
      <!-- our pizza div with all the toppings here -->
</div>

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

Мы добавили totalCost между нашим div и span, используя синтаксис:
{{[vue.js data]}}

Право на!

Наш правый контейнер на данный момент полностью выровнен. Давайте настроим наш левый контейнер.

Установите левый контейнер

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

JS

data: {
    //left container
    topping: "Sauce",
    //right container
    showSauce: false,
    showWedgeCheese: false,
    showStringCheese: false,
    showPepperoni: false,
    currentPrice: 0,
    totalCost: "$0"
  },

Это должно быть просто. Мы присваиваем значение «Соус» данным, называемым топпингом, которые нам нужно вставить в тег HTML под нашим левым контейнером:

HTML

<div class="left-container">
   <div class="option">{{topping}}?</div>
</div>

Единственное, что следует упомянуть, это то, что я добавил "?" сразу после {{topping}}, поскольку мы спрашиваем, хочет ли пользователь добавить топпинг. Кроме того, опция снова предопределена в CSS нашего шаблона, так что не беспокойтесь.

Теперь мы должны увидеть:

Хорошо, у нас есть начальный текст для нашей первой начинки. Теперь нам нужно изображение в чистом виде CSS для нашей вершины. Это, опять же, предопределено в нашем CSS. Вы можете просто скопировать и вставить следующее:

HTML

<div class="left-container">
      <div class="option">{{topping}}?</div>
      <div class="option-container">
        <div class="sauce-can">
          <div class="top-rim">
          </div>
          <div class="bottom-rim">
          </div>
          <div class="red-label">
          </div>
          <div class="badge">
          </div>
        </div>
      </div>
    </div>

Я добавил div с классом option-container, который содержит наше чистое изображение CSS. Затем я добавил все блоки, составляющие контейнер для соуса, который мы видим ниже:

Выглядит хорошо!

Далее, наверное, проще всего будет сделать следующее:

  1. Добавьте наши кнопки Да и Нет
  2. Функция запуска для обработки пользовательского ввода
  3. Добавляем данные для управления условным рендерингом нашего соуса
  4. Добавьте обработчики событий к кнопкам Да и Нет
  5. Перейти к следующему покрытию

Давайте выберем номер 1 из нашего списка, добавив следующие предопределенные кнопки в наш HTML и текст кнопок в данных нашего экземпляра Vue:

HTML

<div class="left-container">
  <!-- Topping text and topping pure css image stuff here -->
  <div class="yes-button">{{yesButton}}</div>
  <div class="no-button">{{noButton}}</div>
</div>

JS

data: {
    //left container
    topping: "Sauce",
    yesButton: "Yes",
    noButton: "No",
    //right container stuff follows
}

Теперь мы видим наши кнопки:

Прохладный!

Теперь давайте перейдем к написанию логики для обработки пользовательского ввода. Для начала давайте добавим данные в наш экземпляр Vue, чтобы наше изображение на чистом CSS можно было визуализировать условно:

JS

data: {
    //left container
    topping: "Sauce",
    yesButton: "Yes",
    noButton: "No",
    showSauceCan: true,
    //right container stuff follows
}

Затем мы добавляем v-if к родительскому div соуса can в нашем HTML, чтобы рендеринг контролировался showSauceCan:

JS

<div class="option-container">
   <div v-if="showSauceCan" class="sauce-can">
      <div class="top-rim">
      </div>
      <div class="bottom-rim">
      </div>
      <div class="red-label">
      </div>
      <div class="badge">
      </div>
   </div>
</div>

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

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

JS

methods: {
    processInput: function(selection){
      
    }
}

Давай подумаем об этом. Эта функция будет вызываться при нажатии любой кнопки. У нас есть две кнопки, и в зависимости от того, какая кнопка была нажата, будет зависеть то, что мы делаем. Следовательно, мы должны указать, какая кнопка вызывала функцию. Итак, мы передадим параметр, обозначенный как selection в нашей функции ,, который будет либо 1, либо 2. Если мы передадим 1, мы сможем узнать что была нажата кнопка "Да". Если мы введем 2, мы сможем узнать, что была нажата кнопка «Нет».

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

HTML

<div @click="processInput(1)" class="yes-button">{{yesButton}}</div>
<div @click="processInput(2)" class="no-button">{{noButton}}</div>

@ - это сокращение от v-on. v-on: [event] - это то, как мы используем обработчики событий в Vue.js. Итак, наш код говорит: «Если я нажму кнопку, я вызову processInput. Я передаю 1 как параметр для нашей кнопки «Да» и 2 как параметр для нашей кнопки «Нет». Следовательно, функция может обрабатывать вводимые пользователем данные ».

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

JS

processInput: function(selection){
      if(selection === 1){
        //yes button clicked and do stuff accordingly
      } else if (selection === 2){
        //yes button clicked and do stuff accordingly
      }
}

Итак, что мы хотим делать, если щелкнули Да или Нет?

Если нажать «Да», нам нужно установить для showSauce значение true, чтобы соус появлялся на пицце в правильном контейнере.

JS

processInput: function(selection){
      if(selection === 1){
        //yes button clicked and do stuff accordingly
        this.showSauce = true
      } else if (selection === 2){
        //yes button clicked and do stuff accordingly
      }
}

Прохладный!

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

data: {
  prices: [2,2,3,3,3],
  //count which option we are on
  stage: 1
}

Нам нужно будет отслеживать, какой вариант мы используем, чтобы знать, к какой цене обращаться, поэтому я также добавил некоторые данные, называемые stage. Stage установлен на 1, поскольку мы находимся на нашем первом варианте.

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

JS

processInput: function(selection){
      if(selection === 1){
        //yes button clicked and do stuff accordingly
        this.showSauce = true
        this.currentPrice += this.prices[this.stage-1]
        this.totalCost = "$" + this.currentPrice
      } else if (selection === 2){
        //yes button clicked and do stuff accordingly
      }
      
      this.stage++
      //prep for next option
}

Мы обновляем currentPrice (number) до цены нашего текущего опциона, которую мы получаем, используя индекс this.stage-1 (0). Мы обновляем строку totalCost до $ + 2 или $ 2.

Аккуратный!

Нам просто нужно сделать быструю настройку, мы хотим, чтобы условный рендеринг нашего левого контейнера чистых изображений CSS обрабатывался для ввода «Да», специфичного для каждого этапа. Итак, давайте обернем this.showSauce таким выражением if:

JS

      if(selection === 1){
        //yes button clicked and do stuff accordingly
        if(this.stage === 1){
          this.showSauce = true
        }
        this.currentPrice += this.prices[this.stage-1]
        this.totalCost = "$" + this.currentPrice
      } else if (selection === 2){
        //do nothing
      }

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

Во-первых, мы добавим следующее предопределенное изображение в чистом CSS, которое вы можете скопировать и вставить:

HTML

<div class="option-container">
 <!-- Sauce Can -->
   <div class="shredded-cheese-wedge">
     <div class="wedge-circle-1"></div>
     <div class="wedge-circle-2"></div>
     <div class="wedge-circle-3"></div>
   </div>
</div>

Затем давайте добавим данные, чтобы мы могли управлять условным рендерингом:

JS

data: {
    //left container
    topping: "Sauce",
    yesButton: "Yes",
    noButton: "No",
    showSauceCan: true,
    showShreddedCheese: false,
}

Мы установили для него значение false, потому что не хотим, чтобы он отображался в начале.

Теперь давайте переключим showShreddedCheese в значение true, чтобы мы могли видеть его после того, как выключим банку соуса. Мы также хотим изменить вывод так, чтобы он отображал «тертый сыр». Обратите внимание: мы заключим это в оператор if, чтобы это произошло только на этапе 1.

JS

processInput: function(selection){
      if(selection === 1){
        //yes button clicked and do stuff accordingly
        if(this.stage === 1){
          this.showSauce = true
        }
        this.currentPrice += this.prices[this.stage-1]
        this.totalCost = "$" + this.currentPrice
      } else if (selection === 2){
        //yes button clicked and do stuff accordingly
      }
      //left container pure css image
      if(this.stage === 1){
        this.showSauceCan = false
        this.showShreddedCheese = true
        this.topping = "Shredded Cheese"
       }
      this.stage++
    }

Наконец, мы можем просто добавить v-if, чтобы рендеринг топпинга из тертого сыра контролировался showShreddedCheese.

HTML

<div v-if="showShreddedCheese" class="shredded-cheese-wedge">
   <div class="wedge-circle-1"></div>
   <div class="wedge-circle-2"></div>
   <div class="wedge-circle-3"></div>
</div>

Мы должны увидеть следующее, если нажмем Да.

И если мы нажмем «Нет» ...

Холодные бобы!

Хорошо, мы успешно обработали наш первый вариант. Мы будем повторять все, что только что сделали, для всех остальных начинок, пока не закончим.

Для тертого сыра мы хотим, чтобы при нажатии кнопки «Да» в правом контейнере отображалась начинка на изображении пиццы. Следовательно, мы можем просто сделать:

JS

      if(selection === 1){
        //yes button clicked and do stuff accordingly
        if(this.stage === 1){
          this.showSauce = true
        } else if(this.stage === 2){
          this.showStringCheese = true
        }
        this.currentPrice = this.prices[this.stage-1]
        this.totalCost = "$" + this.currentPrice
      } else if (selection === 2){
        //do nothing
      }

Мы также пишем логику, специфичную для этого этапа, которая не зависит от Да или Нет в processInput.

JS

      if(this.stage === 1){ 
        this.showSauceCan = false
        this.showShreddedCheese = true
        this.topping = "Shredded Cheese"
      } else if(this.stage === 2){ 
        this.showShreddedCheese = false
        //next toppings' boolean = true
        this.topping = "Mozzarella Cheese"
      }
     this.stage++

Затем давайте добавим логические данные, которые определяют, будет ли отображаться наш следующий вариант, сыр Моцарелла. Я также добавлю showPepperoni, пока мы на нем, что понадобится для нашего следующего этапа:

data: {
    //left container
    topping: "Sauce",
    yesButton: "Yes",
    noButton: "No",
    showSauceCan: true,
    showShreddedCheese: false,
    showMozzarellaCheese: false,
    showPepperoniTopping: false,
}

Теперь мы можем добавить возврат и обновить наш код в processInput:

JS

      if(this.stage === 1){ 
        this.showSauceCan = false
        this.showShreddedCheese = true
        this.topping = "Shredded Cheese"
      } else if(this.stage === 2){ 
        this.showShreddedCheese = false
        this.showMozzarellaCheese = true
        this.topping = "Mozzarella Cheese"
      }
      this.stage++

Чтобы завершить этот этап, нам просто нужно добавить предопределенное изображение на чистом CSS для Моцареллы и добавить v-if. Я также добавлю изображение пепперони в чистом CSS, пока мы будем работать с ним с помощью v-if:

HTML

<div v-if="showMozzarellaCheese" class="moz-wedge">
</div>
<div v-if="showPepperoniTopping" class="pep-option">
</div>

Хорошо, если мы это проверим, то многое у нас получилось:

Прохладный! Теперь нам просто нужно обработать ввод пользователя для нашего сыра моцарелла и пепперони.

Итак, мы повторяем то, что делали раньше, но теперь для этапа 3:

JS

processInput: function(selection){
      if(selection === 1){
        //yes button clicked and do stuff accordingly
        if(this.stage === 1){
          this.showSauce = true
        } else if(this.stage === 2){
          this.showStringCheese = true
        } else if(this.stage === 3){
          this.showWedgeCheese = true
        }
        this.currentPrice += this.prices[this.stage-1]
        this.totalCost = "$" + this.currentPrice
      } else if (selection === 2){
        //do nothing
      }
      if(this.stage === 1){ 
        this.showSauceCan = false
        this.showShreddedCheese = true
        this.topping = "Shredded Cheese"
      } else if(this.stage === 2){ 
        this.showShreddedCheese = false
        this.showMozzarellaCheese = true
        this.topping = "Mozzarella Cheese"
      } else if(this.stage === 3){ 
        this.showMozzarellaCheese = false
        this.showPepperoniTopping = true
        this.topping = "Pepperoni"
      }
      this.stage++
    }
  }

Теперь у нас должно получиться ...

Отлично!

Теперь давайте сделаем то же самое для обработки ввода параметра пепперони:

JS

processInput: function(selection){
      if(selection === 1){
        //yes button clicked and do stuff accordingly
        if(this.stage === 1){
          this.showSauce = true
        } else if(this.stage === 2){
          this.showStringCheese = true
        } else if(this.stage === 3){
          this.showWedgeCheese = true
        } else if(this.stage === 4){
          this.showPepperoni = true
        }
        this.currentPrice += this.prices[this.stage-1]
        this.totalCost = "$" + this.currentPrice
      } else if (selection === 2){
        //do nothing
      }
      if(this.stage === 1){ 
        this.showSauceCan = false
        this.showShreddedCheese = true
        this.topping = "Shredded Cheese"
      } else if(this.stage === 2){ 
        this.showShreddedCheese = false
        this.showMozzarellaCheese = true
        this.topping = "Mozzarella Cheese"
      } else if(this.stage === 3){ 
        this.showMozzarellaCheese = false
        this.showPepperoniTopping = true
        this.topping = "Pepperoni"
      } else if(this.stage === 4){ 
        this.showPepperoniTopping = false
        this.topping = "Order"
      }
      this.stage++
    }

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

Сладкий! Мы почти закончили! А теперь давайте добавим последние штрихи!

Привязка классов и CSS-анимация

Первое, что мы хотим добавить, - это заставить пиццу вращаться, когда она будет готова к заказу.

На самом деле мы справляемся с этим довольно легко благодаря привязке классов Vue.js. Так же, как мы можем контролировать, какой текст мы вводим с чем-то в наши данные, мы можем иметь данные в нашем экземпляре Vue, который контролирует, какой класс активен для элемента.

So…

Мы добавим данные в наш экземпляр Vue, для которого установлено значение pizza, которое является классом по умолчанию для нашей пиццы в правильном контейнере. Когда пицца будет готова к заказу, мы будем манипулировать данными, чтобы для нашей пиццы стал активен другой класс. Мы активируем класс, уже содержащийся в шаблоне, под названием spin-pizza, который добавляет CSS-анимацию, которая вращает пиццу.

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

JS

pizzaClass: "pizza"

Затем мы можем привязать эти данные к элементу, которым хотим управлять:

HTML

<div class="right-container">
  <div class="option"><span id="white">{{totalCost}}</span></div>
     <div :class="pizzaClass">
       
         <!-- Topping css classes here -->
    </div>
</div>

Последняя часть этой привязки класса - установить класс, равный классу spin в нашей функции processInput:

processInput: function(selection){
      if(selection === 1){
        //yes button clicked and do stuff accordingly
        if(this.stage === 1){
          this.showSauce = true
        } else if(this.stage === 2){
          this.showStringCheese = true
        } else if(this.stage === 3){
          this.showWedgeCheese = true
        } else if(this.stage === 4){
          this.showPepperoni = true
        }
        this.currentPrice += this.prices[this.stage-1]
        this.totalCost = "$" + this.currentPrice
      } else if (selection === 2){
        //do nothing
      }
      if(this.stage === 1){ 
        this.showSauceCan = false
        this.showShreddedCheese = true
        this.topping = "Shredded Cheese"
      } else if(this.stage === 2){ 
        this.showShreddedCheese = false
        this.showMozzarellaCheese = true
        this.topping = "Mozzarella Cheese"
      } else if(this.stage === 3){ 
        this.showMozzarellaCheese = false
        this.showPepperoniTopping = true
        this.topping = "Pepperoni"
      } else if(this.stage === 4){ 
        this.showPepperoniTopping = false
        this.topping = "Order"
        this.pizzaClass = "spin-pizza"
      }
      this.stage++
    }

Вот CSS-класс и ключевой кадр spin-pizza, содержащиеся в шаблоне:

спин-пицца

.spin-pizza{
  animation: spinPizza 1s infinite;
  position: absolute;
  height: 40%;
  width: 45%;
  top: 30%;
  left: 27.5%;
  border-radius: 50%;
  background: #FDE4A7;
  z-index: 2;
}

@keyframes spinPizza

//animations
@keyframes spinPizza{
  0%{
    -webkit-transform: rotate(0deg); 
    transform: rotate(0deg);
}

Хорошо, выглядит круто!

Давайте завершим это, просто изменив текст в нашем левом контейнере на «Out of Order» на вводе пользователя, поскольку мы не хотим принимать заказ. Мы также удалим наши кнопки с помощью условного рендеринга.

Во-первых, давайте добавим логическое значение в data: {} для управления условным отображением наших кнопок.

JS

buttonsOn: true,

Затем давайте добавим v-if в наш HTML:

HTML

<div v-if="buttonsOn" @click="processInput(1)" class="yes-button">{{yesButton}}</div>
<div v-if="buttonsOn" @click="processInput(2)" class="no-button">{{noButton}}</div>

Наконец, мы просто добавляем следующее в нашу функцию processInput для обработки этого последнего этапа:

JS

processInput: function(selection){
      if(selection === 1){
        //yes button clicked and do stuff accordingly
        if(this.stage === 1){
          this.showSauce = true
        } else if(this.stage === 2){
          this.showStringCheese = true
        } else if(this.stage === 3){
          this.showWedgeCheese = true
        } else if(this.stage === 4){
          this.showPepperoni = true
        }
        if(this.stage !== 5){
          this.currentPrice += this.prices[this.stage-1]
          this.totalCost = "$" + this.currentPrice
        }
      } else if (selection === 2){
        //do nothing
      }
      if(this.stage === 1){ 
        this.showSauceCan = false
        this.showShreddedCheese = true
        this.topping = "Shredded Cheese"
      } else if(this.stage === 2){ 
        this.showShreddedCheese = false
        this.showMozzarellaCheese = true
        this.topping = "Mozzarella Cheese"
      } else if(this.stage === 3){ 
        this.showMozzarellaCheese = false
        this.showPepperoniTopping = true
        this.topping = "Pepperoni"
      } else if(this.stage === 4){ 
        this.showPepperoniTopping = false
        this.topping = "Order"
        this.pizzaClass ="spin-pizza"
      } else if(this.stage === 5){ 
        this.buttonsOn = false
        this.topping = "Out of Order"
      }
      this.stage++
    }

Здесь мы отключаем наши кнопки и меняем текст в левом контейнере на «Out of Order». Мы также добавляем оператор if, чтобы не обновлять общую стоимость при нажатии кнопки «Да» на предыдущем этапе, где указано только «Заказать».

МЫ ЗАВЕРШЕНО!

Живая демонстрация: http://codepen.io/mikemang/live/9fb4d84647a0ed6cc52b987624743859

Полный код: http://codepen.io/mikemang/pen/9fb4d84647a0ed6cc52b987624743859/?editors=1010

Будущие улучшения

  1. Вы можете создать свои собственные изображения на чистом CSS и попробовать добавить больше анимации, эффектов перехода и / или начинки для пиццы (или, возможно, несколько пицц).
  2. Вскоре я выпущу новый видеокурс под названием Используйте изображения на чистом CSS и Vue.js для создания забавных приложений. В этом курсе рассматриваются основы Vue.js с особым упором на создание забавных, творческих приложений, как в этом руководстве. Вы можете зарезервировать место, нажав на предоставленную мной ссылку.

Любые отзывы приветствуются!

Ура,
Майк Мангиаларди