5

我正在尝试学习如何使用通过 Webpacker gem 生成的带有 Vuejs 的 Rails 5.1 构建应用程序。

$ rails new myvueapp --webpack=vue

如何在 Vue 组件之间来回传递实例变量数据,以将我的数据输入/输出数据库?

例如,假设我有一个带有用户名和电子邮件字段的用户模型。是否有一个简单的示例说明如何将实例变量 @user 数据从控制器传递到组件?

我相信有两种方法可以做到这一点:

(1) 在控制器中,render :json => @user使用 fetch API 或 Axios 之类的东西来检索 .vue 组件中的数据。

-或者-

(2) 在视图中使用类似于示例<%= javascript_pack_tag 'hello_vue' %><%= content_tag ... %>内容。

当我做这个<%= javascript_pack_tag 'hello_vue' %>例子时,我可以看到“Hello Vue!” 来自组件“消息”变量中的数据,但我无法找到实例变量数据的示例,例如:@user 数据,正在传入和传出 Rails。

任何有关如何传递@user 数据的示例都将不胜感激。

谢谢你。

4

4 回答 4

2

我做了一些有效但我不太喜欢的事情:在window范围内创建一个方法,例如:

// app/javascript/packs/some_app.js

window.someAppPack = function (var1, var2) {
  // ...
  new Vue({
    // ...
    data () {
      return {
        var1,
        var2,
      }
    }
    // ...
  })
}

在 Rails 模板中:

<%= javascript_pack_tag 'somePack' %>

<script>
  someAppPack(#{raw @var1.to_json}, #{raw @var2.to_json})
</script>

这对我来说似乎很脏,我想知道它的好处:

  • Vue 应用程序应该是响应式的,因此数据可能会在某个时候更新,并且会调用 JSON 资源。这使得传递原始数据毫无意义。
  • 如果 Vue 仅用于使页面的某些部分具有响应性,那么当我们可以将“内联”Vue 与标准 Rails 管道一起使用时,为什么还要使用所有 webpack 的东西呢?
于 2019-06-10T06:54:43.460 回答
1

我找到了一种利用 gem gon的力量来完成这项工作的方法。

  1. 在控制器中
class MyController < ApplicationController
  def index
    @user = User.first
    gon.user = @user
  end
end
  1. 在布局:
# app/views/layouts/application.html.erb
<%= Gon::Base.render_data %>
  1. 在 webpacker 的入口文件中
// app/javascript/packs/hello_vue.js
import Vue from 'vue'
import HelloVue from '../views/HelloVue.vue'

window.addEventListener('load', () => {
  const app = new Vue({
    el: document.getElementById('div-you-want-to-mount'),
    components: { HelloVue },
    render: h => h(HelloVue, { props: gon })
  }).$mount()
})
  1. 在 HelloVue.vue 中
<template>
  <div id="hello">
    User: {{ user }}
  </div>
</template>

<script>
export default {
  props: ['user']
}
</script>
于 2020-08-30T04:28:58.070 回答
1

我想我遇到了同样的问题,但是道具帮助了我。

app/views/**/*.html.erb

<div id="app" data-initial-value="#{raw(html_escape(@var.to_json))}"></div>
<%= javascript_pack_tag 'app' %>

应用程序/javascript/packs/app.ts

import Vue from 'vue'
import App from '../app.vue'

Vue.config.productionTip = false;

document.addEventListener('DOMContentLoaded', () => {
    const app = new Vue({
        render: h => h(App, {
            props:{
                value: JSON.parse(document.querySelector("#app").dataset.initialValue)
            }
        })
    }).$mount()
    document.body.appendChild(app.$el)
})

应用程序/javascript/app.vue

<template>
  <div>
  {{ value.content }}
  </div>
</template>

<script lang="ts">
export default {
  name: "App",
  props: {
    value: Object
  }
};
</script>
于 2020-08-16T05:33:50.383 回答
1

我不是 100% 确定你想要完成什么,但我可以想到两种方法来做到这一点。

  1. v-model在表格上使用。检索或更新的任何值都将立即在您的 Vue 实例中可用。(例如<%= f.input :username, input_html: { 'v-model': 'username' } %>

  2. 使用数据属性。假设您有一个具有@user变量的控制器。

然后在你看来,你可以做类似的事情(这可能不是 100% 正确,因为它只是来自记忆):

<% simple_form_for @user do |f| %>
  <%= f.input :username, input_html: { id: 'user_username', data: { username: @user.username } } %>
  <%= f.input :email, input_html: { id: 'user_email', data: { email: @user.email } } %>
<% end %>

然后您可以使用 JavaScript 访问数据属性。在这些示例中,由于两者都是表单,因此最好使用v-model,但您可以将数据属性用于非表单内容。例如,我经常为 AJAX 请求中使用的 URI 使用数据属性,这可能因测试站点和生产环境等不同而不同。

于 2017-08-21T16:54:20.167 回答