您的位置:首页 > 产品设计 > UI/UE

如何在 Rails 中搭配 Turbolinks 使用 Vue

2017-08-09 23:04 176 查看

[Rails] Vue-outlet for Turbolinks

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

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


<!--
./app/javascript/packs/hello_turbolinks.vue
-->

<template>
<div>
<h4>{{ message }}</h4>
<ul>
<li>Object: {{ obj }} </li>
<li>Number: {{ num }} </li>
<li>Array: {{ arr }} </li>
<li>String: {{ str }} </li>
</ul>
</div>
</template>

<script>
export default {
props: ['obj', 'arr', 'num', 'str'],
data: function () {
return {
message: 'Hello, Vue and Turbolinks'
}
}
}
</script>

<style scoped>
p {
font-size: 2em;
text-align: center;
}
</style>

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('www.rcsx.org [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' %>


<!--
./app/views/layouts/application.html.erb
-->
<!DOCTYPE html>
<html>
<head>
<title>RailsSandboxVue</title>
<%= 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' %>
</head>

<body>
<%= yield %>
</body>
</html>


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


Import Vue component in template

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

<!--
./app/views/users/index.html.erb
-->

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

<!-- Import Vue Component -->
<div data-vue-components-outlet="hello-turbolinks">
<hello-turbolinks
:obj="<%= @hello_message[:obj].to_json %>"
:arr="<%= @hello_message[:arr] %>"
:str="<%= @hello_message[:str] %>"
:num="<%= @hello_message[:num] %>"
></hello-turbolinks>
</div>
<!-- End of Import Vue Component -->

<%= 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

使用方式如下:

<!--
./app/views/users/index.html.erb
-->

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

<!-- Import Vue Component by Helper -->
<%= vue_outlet do %>
<hello-turbolinks
:obj="<%= @hello_message[:obj].to_json %>"
:arr="<%= @hello_message[:arr] %>"
:str="<%= @hello_message[:str] %>"
:num="<%= @hello_message[:num] %>"
>
<% end %>
<!-- End of Import Vue Component by Helper -->

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

<!--
./app/views/users/index.html.erb
-->

<!-- With <p> -->
<%= vue_outlet tag: 'p' do %>
<hello-turbolinks
:obj="<%= @hello_message[:obj].to_json %>"
:arr="<%= @hello_message[:arr] %>"
:str="<%= @hello_message[:str] %>"
:num="<%= @hello_message[:num] %>"
>
<% end %>
<!-- End of With <p> -->
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: