如何在 Rails 中搭配 Turbolinks 使用 Vue
[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
yarnScaffold the app
# Scaffold the app
bin/rails g scaffold User name email
# Create database and migrate
bin/rails db:setup
bin/rails db:migrateCreate 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> -->如何在 Rails 中搭配 Turbolinks 使用 Vue的更多相关文章
- 如何在Rails中执行Get/Post/Put请求
		require 'open-uri' require 'json' require 'net/http' class CoupleController < ApplicationControll ... 
- 如何在 Vite 中使用 Element UI + Vue 3
		在上篇文章<2021新年 Vue3.0 + Element UI 尝鲜小记>里,我们尝试使用了 Vue CLI 创建 Vue 3 + Element UI 的项目,而 Vue CLI 实际 ... 
- Vue:如何在vue-cli中创建并引入自定义组件
		一.创建并引入一个组件 1.创建组件 vue-cli中的所有组件都是存放在components文件夹下面的,所以在components文件夹下面创建一个名为First.vue的自定义组件: <t ... 
- rails中如何在a标签中添加其他标签
		最近在用rails写一个项目练练手,然后遇到了一个问题,就是用 <% link_to("首页", root_path) %> 生成一个a标签,之后就在想我怎么在这个a标 ... 
- 我是如何在SQLServer中处理每天四亿三千万记录的
		首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文中有不对的地方,请各位数据库大牛给予指正,以便我能够更好的处理此次业务. ... 
- 【转】我是如何在SQLServer中处理每天四亿三千万记录的
		原文转自:http://blog.jobbole.com/80395/ 首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文 ... 
- 如何在Vue2中实现组件props双向绑定
		Vue学习笔记-3 前言 Vue 2.x相比较Vue 1.x而言,升级变化除了实现了Virtual-Dom以外,给使用者最大不适就是移除的组件的props的双向绑定功能. 以往在Vue1.x中利用pr ... 
- 如何在SQLServer中处理每天四亿三千万记录
		首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文中有不对的地方,请各位数据库大牛给予指正,以便我能够更好的处理此次业务. ... 
- (转)我是如何在SQLServer中处理每天四亿三千万记录的
		首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文中有不对的地方,请各位数据库大牛给予指正,以便我能够更好的处理此次业务. ... 
随机推荐
- jquery解析xml,获取xml标签名
			先给一个简单的XML,结构如下 <?xml version="1.0" encoding="uft-8" ?> <msg> <ro ... 
- c#在不安装Oracle客户端的情况下与服务器上的Oracle数据库交互
			概述: C#通过使用ADO的方式在未安装Oracle数据库的前提下,客户端程序远程访问服务器,会出现:“System.Data.OracleClient 需要 Oracle 客户端软件 8. ... 
- HDU 3001 Travelling (状压DP,3进制)
			题意: 给出n<=10个点,有m条边的无向图.问:可以从任意点出发,至多经过同一个点2次,遍历所有点的最小费用? 思路: 本题就是要卡你的内存,由于至多可经过同一个点2次,所以只能用3进制来表示 ... 
- 如何选择Web开发框架
			下面先来看看为什么要使用Web开发框架一 使用框架的必然性框架,即framework.其实就是某种应用的半成品,把不同应用程序中有共性的一些东西抽取出来,做成一个半成品程序,这样的半成品就是所谓的程序 ... 
- [uva]AncientMessages象形文字识别 (dfs求连通块)
			非常有趣的一道题目,大意是给你六种符号的16进制文本,让你转化成二进制并识别出来 代码实现上参考了//http://blog.csdn.net/u012139398/article/details/3 ... 
- Win10激活方法(企业版)
			Win10激活 注意:以管理员身份运行,需要电脑有网(亲测激活企业版没问题) 然后一条一条复制执行 slmgr /ipk NPPR9-FWDCX-D2C8J-H872K-2YT43 slmgr /sk ... 
- centos7-httpd虚拟主机
			Apache虚拟主机: 一台WEB服务器发布单个网站会非常浪费资源,所以一台WEB服务器上会发布多个网站, 在一台服务器上发布多网站,也称之为部署多个虚拟主机,WEB虚拟主机配置方法有三种: 基于单I ... 
- OTOH
			OTOH n 网络用语 On the Other Hand 另一方面 [例句]OTOH, pressure on the keys of a digital AFTER bottoming can b ... 
- 解决 cocos2dx iOS/mac 设置纹理寻址模式后纹理变黑的问题
			sprite:getTexture():setTexParameters(gl.LINEAR,gl.LINEAR,gl.REPEAT,gl.REPEAT) 在安卓设备上,设置了纹理自定义寻址模式,纹理 ... 
- tensorflow目标检测API安装及测试
			1.环境安装配置 1.1 安装tensorflow 安装tensorflow不再仔细说明,但是版本一定要是1.9 1.2 下载Tensorflow object detection API 下载地址 ... 
