如何在 Rails 中搭配 Turbolinks 使用 Vue

[Rails] Vue-outlet for Turbolinks

在踩了 Rails + Turbolinks + Vue 的許多坑後,整理 @andyyu0920 的作法並和大家分享。

Initialize the App

# initialize the app
rails new rails_sandbox_vue --database=postgresql --webpack=vue

# install package
bundle
yarn

Scaffold the app

# Scaffold the app
bin/rails g scaffold User name email

# Create database and migrate
bin/rails db:setup
bin/rails db:migrate

Create Vue Component

./app/javascript/packs/ 中建立 vue component hello_turbolinks.vue







Create Vue Adapter

建立 vue_adapter.js,在 import Vue 的地方要載入 vue.esm.js 可以 compile template 的版本。另外要把需要使用到的 Vue Component 在這裡執行註冊:

// ./app/javascript/packs/vue_adapter.js
import Vue from 'vue/dist/vue.esm.js'
import HelloTurbolinks from './hello_turbolinks'

/**
 * Register components
 */
Vue.component('hello-turbolinks', HelloTurbolinks)

function VueConstructor () {
  let outlets = document.querySelectorAll('[data-vue-components-outlet]')
  outlets.forEach(function (outlet, index) {
    let id = outlet.getAttribute('data-vue-components-outlet')
    new Vue({
      el: '[data-vue-components-outlet=' + id + ']'
    })
  })
}

document.addEventListener('turbolinks:load', function () {
  VueConstructor()
})

Notice:
-記得 import 的 Vue 要匯入的是 vue.esm.js
-記得註冊要使用的 Vue Component

add vue_adapter in head

在 layouts/application.html.erb 中的 head 中加入 <%= javascript_pack_tag 'vue_adapter', 'data-turbolinks-track': 'reload' %>




  
    RailsSandboxVue
    <%= csrf_meta_tags %>

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'vue_adapter', 'data-turbolinks-track': 'reload' %>
  

  
    <%= yield %>
  

Notice: 記得要把 javascript_pack_tag 放在 head 當中

Import Vue component in template

我們把 Vue 的組件載入 index.html.erb 中,data-vue-components-outlet 這個屬性是關鍵字,後面放要載入的 Vue 組件名稱:




<% @hello_message = {num: 1, str: '2', arr: [1, 2, 3], obj: {name: 'foo', age: 12}} %>


<%= link_to 'New User', new_user_path %>

完成

分別開兩個 terminal 到 app 目錄底下,分別執行:

bin/webpack-dev-server
bin/rails s

就可以看到 Vue Component 正確運作了。

加入 View Helper

我們也可以寫一個 Rails View Helper 來方便我們使用 Vue 組件:

./app/helpers/ 中建立一支 vue_helper.rb

# ./app/helpers/vue_helper.rb
module VueHelper
  def vue_outlet(html_options = {})
    html_options = html_options.reverse_merge(data: {})
    html_options[:data].tap do |data|
      data[:vue_components_outlet] = "_v" + SecureRandom.hex(5)
    end
    html_tag = html_options[:tag] || :div
    html_options.except!(:tag)
    content_tag(html_tag, '', html_options) do
      yield
    end
  end
end

使用方式如下:



<% @hello_message = {num: 1, str: '2', arr: [1, 2, 3], obj: {name: 'foo', age: 12}} %>


<%= vue_outlet do %>
  
<% end %>

如果需要 tag 不想要使用 div 可以加上 options:




<%= vue_outlet tag: 'p' do %>
  
<% end %>

檔案範例

template-rails-vue-turbolinks @ Github

開發者

  • @andyyu0920 @ segmentfault

  • Andyyou @ Github

參考

  • Make Vue.js works with Ruby on Rails and Turbolinks 5 @ Gist

  • A Vue mixin to fix Turbolinks caching @ Vue Turbolinks

  • VueJs and Turbolinks @ turbolinks

你可能感兴趣的:(turbolinks,vue.js,ruby-on-rails)