VueJS як фронтенд для Rails

12 хв. читання

VueJS — одна з зірок фронтенд екосистеми JavaScript, що найшвидше зростає. Vue втілює просте й зручне рішення для проектування фронтенду без зайвих складнощів, а також надає більш елегантний спосіб спрощення створення скриптів та стилів, об'єднуючи їх у компоненти. Це захищає ваш сайт від конфліктів стилів, а також забезпечує прозору структуру для окремих частин коду інтерфейсу.

Початок роботи

Короткі інструкції зі встановлення.

gem install rails --version "5.2.0.rc1"
rails _5.2.0.rc1_ new vue_example --webpack=vue
cd vue_example

З цього моменту ви можете розпочати роботу з VueJS без підтримки CoffeeScript (ми додамо її пізніше). Rails включає приклади інтеграції VueJS в інтерфейс, і того, що називається компонентом. Ці файли доступні в app/javascript/packs/hello_vue.js, а компонент — в app/javascript/hello.vue. Якщо ви хочете випробувати себе, щоб вивчити процес їх інтеграції, то це хороше місце, щоб розпочати.

Приклад Rails Vue

Слідуйте інструкціям у цьому розділі, якщо хочете спробувати виконати невелике завдання по Rails. Закоментуйте код в hello_vue.js та розкоментуйте код в останньому розділі:

import TurbolinksAdapter from 'vue-turbolinks';
import Vue from 'vue/dist/vue.esm'
import App from '../app.vue'

Vue.use(TurbolinksAdapter)

document.addEventListener('turbolinks:load', () => {
  const app = new Vue({
    el: '#hello',
    data: {
      message: "Can you say hello?"
    },
    components: { App }
  })
})

Створіть маршрут і контролер для роботи з ним, та додайте кореневий маршрут до конфігурації, щоб вказати на нього.

rails g controller LandingPage index

Додайте у config/routes.rb файл:

root to: "landing_page#index"

Ви можете перевірити, що це працює, запустивши rails s і прописавши у браузері http://localhost:3000. Виникає завдання визначити, який HTML- і JavaScript-пов'язаний код помістити в шаблон сайту й цільову сторінку, щоб працювали обидва VueJS приклади. Перейдімо до створення нашої власної реалізації форми у VueJS.

Приклад форми Vue JS Rails

У цьому прикладі ми збираємося створити форму для письменника, щоб відстежувати документи — вони міститимуть тему, тіло тексту і стан перегляду.

По-перше, згенеруємо основи для ресурсу документа.

rails g scaffold Document subject:string:index body:text state:integer:index

Потім відредагуйте файл міграції під db/migrate і змініть рядок стану, щоб вказати значення за замовчуванням.

t.integer :state, default: 0, null: false

Тепер ми можемо запустити rails db:migrate, щоб оновити БД. Потім потрібно оновити нашу модель для різних станів, в яких може знаходитися документ. Відкрийте app/models/document.rb та додайте наступне:

class Document < ApplicationRecord
  enum state: [:concept, :alpha, :beta, :draft, :publish]
end

На цьому етапі ми вже зможемо побачити зміни, які будемо робити, тому спочатку створімо файл CoffeeScript, а потім запустимо сервер Rails, щоб можна було оновити наш браузер для роботи з результатами. У новому вікні терміналу запустіть з вашого каталогу проекту наступне:

touch app/javascript/packs/documents.coffee
rails s

Тепер, відкривши вікно браузера, перейдіть до http://localhost:3000/documents. Тут ви можете використовувати Rails CRUD для ресурсу вашого документа. Ми будемо замінювати форму на VueJS-специфічну.

Потрібно додати можливість вставити наш JavaScript пакет у заголовок сайту. Тому відкрийте шаблон вашого застосунку app/views/layouts/application.html.erb і додайте між тегами <head> та </head> наступне:

<% if content_for? :head %>
  <%= yield :head %>
<% end %>

Тепер у нас є хук, який ми можемо використовувати на будь-якій сторінці, якщо використаємо content_for(:head) і надамо йому блок коду, який буде записаний у розділ заголовку наших конкретних сторінок.

Відкрийте app/views/documents/_form.html.erb і видаліть весь вміст файлу. Ця форма використовується для нових записів і оновлення наявних записів для наших документів у Rails. Вставимо спершу блок коду заголовку для завантаження того, що буде нашим кодом VueJS.

<% content_for :head do -%> 
  <%= javascript_pack_tag 'documents' %>
<% end -%>

Спроба завантажити у браузері localhost:3000/documents не спрацює. Нам потрібно, щоб він розпізнав розширення .coffee. Ви можете зупинити роботу сервера в терміналі за допомогою CTRL-C і запустити наступне:

bundle exec rails webpacker:install:coffee

Застереження: обов'язково робіть встановлення нових функцій невеликими кроками, перевіряючи їх роботу перед додаванням інших функцій. Інакше вони, та набір команд yarn add перед тестуванням, може призвести до того, що ця функція не буде працювати взагалі.

Тепер ви знову можете запустити rails s й повернутися на localhost:3000/documents, побачивши, що сторінка завантажується без жодних помилок. Продовжимо працювати над формою. Оновімо файл, над яким ми тільки-но працювали, додавши наступне:

<% content_for :head do -%>
  <%= javascript_pack_tag 'documents' %>
<% end -%>

<%= content_tag :div,
  id: "document-form",
  data: {
    document: document.to_json(except: [:created_at, :updated_at])
  } do %>

  <label>Subject</label>
  <input type="text" v-model="document.subject" />

  <label>State</label>
  <select v-model="document.state">
    <%= options_for_select(Document.states.keys, "concept") %>
  </select>

  <label>Body</label>
  <textarea v-model="document.body" rows="20" cols="60"></textarea>

  <br />

  <button v-on:click="Submit">Submit</button>

<% end %>

Перш ніж писати CoffeeScript реалізацію для нашого коду VueJS, розглянемо коротко, що у нас є у вищевказаному файлі. Перший блок коду, який ми вже обговорювали, завантажить наш ресурс коду CoffeeScript у заголовок через шаблон застосунку. content_tag створить div, який зберігатиме об'єкт документу наших поточних сторінок як JSON. Документ, створений або завантажений у контролер, там конвертується, і використовується кодом VueJS.

Елементи v-model — VueJS-специфічні імена, які наш код буде відстежувати. Виявляється, що для вибору field набагато легше працювати з хелпером options_for_select в Rails , ніж з VueJS методом v-for, оскільки проблематично намагатися змусити його обрати опцію selected. І так, я перепробував для цього півдюжини доступних в інтернеті способів, але всі вони виявилися безрезультатними. Існує доповнення мультивибору, яке ви можете встановити за допомогою Yarn, але для нашого простого варіанту це буде зайвим.

v-on:click викличе функцію Submit у нашому об'єкті Vue (як тільки ми її визначимо) для виконання визначених там дій.

Перш ніж продовжувати, я хотів би поділитися тим, як працювала би базова VueJS реалізація option, якби натомість ми використали її:

<select v-model="document.state">
  <option v-for="state in <%= Document.states.keys.to_json %>"
    :value=state
  >
    {{ state }}
  </option>
</select>

Ви маєте розпізнати шаблон ERB <%= %>, в якому Ruby отримає стани документу й підготує його як JSON. v-for — частина власного DSL Vue, який обробляє контент як звичайний код циклу. Для кожного стану документу він продублює HTML теги <option> і помістить слово заміни для змінної стану в параметр значення і в місце {{ }}.

Остання річ, яку я хотів би зазначити, є в основній документації VueJS:

<my-component
  v-for="(item, index) in items"
  v-bind:item="item"
  v-bind:index="index"
  v-bind:key="item.id"
></my>

Ми поки що не розглядали компоненти, але цим прикладом я хотів би зазначити те, що використання v-bind тут буде виконувати частини в лапках як звичайний JavaScript. Тому кожне із цих значень присвоюється з області видимості JS.

Перейдімо тепер до коду CoffeeScript VueJS для нашої форми.

Код

Нам потрібно встановити деякі Yarn залежності для роботи Vue з Turbolinks в Rails і для більш зручних команд PUT/POST.

yarn add vue-resource vue-turbolinks

Наш код VueJS може бути записаний у app/javascript/packs/documents.coffee. Ви отримаєте додатковий бал, якщо вже усвідомили те, що використовуючи слово 'document', ми використали суперечливе ключове слово JavaScript. Оскільки це так, ми використаємо змінну ourDocument у скрипті, щоб все було ясно і працювало.

import Vue from 'vue/dist/vue.esm'
import TurbolinksAdapter from 'vue-turbolinks'
import VueResource from 'vue-resource'

Vue.use(VueResource)
Vue.use(TurbolinksAdapter)

document.addEventListener('turbolinks:load', () ->
  Vue.http.headers.common['X-CSRF-Token'] = document
    .querySelector('meta[name="csrf-token"]')
    .getAttribute('content')

  element = document.getElementById 'document-form'

  if element != null
    ourDocument = JSON.parse(element.dataset.document)

    app = new Vue(
      el: element

      data: ->
        { document: ourDocument }

      methods: Submit: ->
        if ourDocument.id == null
          @$http # New action
            .post '/documents', document: @document
            .then (response) ->
                Turbolinks.visit "/documents/#{response.body.id}"
                return
              (response) ->
                @errors = response.data.errors
                return
        else
          @$http # Edit action
            .put "/documents/#{document.id}", document: @document
            .then (response) ->
                Turbolinks.visit "/documents/#{response.body.id}"
                return
              (response) ->
                @errors = response.data.errors
                return
        return
  )
)

Подія turbolinks:load — тригер для запуску цього коду кожного разу, коли сторінка завантажується у Rails. Цей код необхідно виконати у розділі <head>, інакше ви отримаєте побічні ефекти у вигляді його відмови завантажуватися без оновлення.

Наступний рядок отримує токен CSRF, який потрібен для верифікації будь-яких даних, надісланих на сервер. Він бере його з того, що нам вручає Rails й присвоює його заголовку відповіді.

Далі у нас є присвоєння елементу з id document-form. Це той id, який ми розмістили раніше в нашому content_tag.

Змінній ourDocument присвоюються дані, які ми розмістили на сторінці як JSON у розділі даних content_tag :div. Вона аналізує дані JSON.

Далі ми створюємо екземпляр об'єкту Vue у JavaScript (CoffeeScript), зробивши його першим параметром element, який є формою документу.

В methods у нас є функція Submit, яка спрацьовує за допомогою кнопки відправлення на сторінці. Наступна за цим умова if перевіряє, чи це новий об'єкт, і нам слід використати шлях Rails "new record" або це наявний об'єкт, і ми використаємо PUT для його оновлення.

@http, post, put та then — це все переваги від vue-resource пакета Yarn, який ми встановили раніше. Просто поглянувши на нього, ви можете побачити, що він публікує деякі дані на URL сервер, а потім дає відповідь. response у лапках є параметром функції, і у нас є два шляхи для нього. Перший шлях — хороша відповідь сервера, а другий — помилка.

Про компоненти

Однією з головних привабливих сторін VueJS є його компоненти. Вони надають єдине місце для кожного компоненту, який ви хочете створити, щоб мати HTML, JavaScript та CSS у їх власному файлі vue. Стилі в цих компонентах не будуть вступати в конфлікт зі стилями де-небудь в іншому місці вашого сайту. Вони — добре організовані сингулярні одиниці коду, які можуть використовуватися в будь-якому місці й можуть бути потенційно розширені або включені в інші компоненти. Думайте про них як про ультимативні будівельні блоки.

Якщо ви виконали завдання, яке було поставлене на початку цієї статті або звернули увагу на приклад компоненту, який ми мимохідь пройшли, то ви, скоріш за все, виявили, що компоненти мають свій власний тег XML/HTML. Вищевказаний приклад називається <my-component>, і він дійовий для HTML документів. Роблячи наведений приклад Rails покаже вам, наскільки просто розташувати компонент у необхідному вам місці.

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 5.8K
Приєднався: 8 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація