Help us understand the problem. What is going on with this article?

Vue.jsの外から情報を渡したい

More than 1 year has passed since last update.

Vue.jsとRailsを組み合わせている時、Rubyの世界からJSの世界に値を楽に渡したいと思ったことはありませんか?
私はあります。

そこでWeb APIを経由せずにデータを渡す方法をいくつか試してみたので、まとめてみました。
※ 以下、vue-cliで生成されたファイルで試しています。

共通

App.vueは共通のものを使用します。
このコンポーネントのpropsに情報が渡れることを目的とします。
追加したのはprops<div>{{ arg1 }}</div>だけです。

src/App.vue
<template>
  <div id="app">
    <div>{{ arg1 }}</div>
    <img src="./assets/logo.png">
    <HelloWorld/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld'

export default {
  name: 'app',
  props: {
    arg1: { type: String, required: true }
  },
  components: {
    HelloWorld
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

同じ変数名で渡す

src/main.jsが読み込まれる前に変数をindex.htmlで定義する

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>test</title>
  </head>
  <body>
    <div id="app"></div>
    <script>
      var arg1 = 'arg1'
    </script>
    <!-- built files will be auto injected -->
  </body>
</html>
src/main.js
import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false

if (typeof arg1 === 'undefined') {
  throw new Error('Not found arg1')
}

new Vue({
  el: '#app',
  template: `<App arg1="${arg1}"/>`,
  components: { App }
})

Appをindex.htmlで書く

Vueインスタンスではtemplateを書かずにindex.htmlで書く

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>test</title>
  </head>
  <body>
    <div id="app">
      <App arg1="arg1"></App>
    </div>
    <!-- built files will be auto injected -->
  </body>
</html>
src/main.js
import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false

new Vue({
  el: '#app',
  components: { App }
})

Rootで受け取る

mountするelementにarg1を書いて、renderが呼ばれたときに取得し、propsで渡す

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>test</title>
  </head>
  <body>
    <div id="app" arg1="arg1"></div>
    <!-- built files will be auto injected -->
  </body>
</html>
src/main.js
import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false

new Vue({
  el: '#app',
  template: '<App/>',
  components: { App },
  render: function(createElement) {
    const arg1 = this.$el.getAttribute('arg1')
    return createElement('App',
      {
        props: {
          arg1: arg1
        }
      })
  }
})

最後に

思いついたものの列挙なので、もっと良い手段やそもそもこんなことしないでいいよというものがあれば教えていただけると嬉しいです

hacosco
再現可能な体験の共有を可能にする「ハコスコ」のエンジニアチームです
https://hacosco.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away