rails 共享变量_如何将Rails实例变量传递给Vue组件

rails 共享变量

by Gareth Fuller

由Gareth Fuller

如何将Rails实例变量传递给Vue组件 (How to pass Rails instance variables into Vue components)

I’m currently working with a legacy Rails application. We are slowly transitioning the front-end from Rails views to a Vue application.

我目前正在使用旧版Rails应用程序。 我们正在将前端从Rails视图逐步过渡到Vue应用程序。

As part of this transition, we have some elements that we want to turn into global Vue components. We want to be able to use these components within our existing Rails views and within a Vue application without having to customize each component to handle both situations.

作为此过渡的一部分,我们希望将某些元素转变为全局Vue组件。 我们希望能够在我们现有的Rails视图和Vue应用程序中使用这些组件,而不必自定义每个组件来处理这两种情况。

Before I share my solution to this problem, here is an example single file Vue component that we want to be able to use in both scenarios (Rails view and Vue Application):

在分享我对这个问题的解决方案之前,这是一个示例单文件Vue组件,我们希望在两个场景(Rails视图和Vue Application)中都可以使用:

// Payments.vue
<template lang="html">  <div id="payments>    <div class="payment" v-for="payment in payments>      {{ payment.amount }}    </div>  </div></template>
<script>export default {  name: 'payments'
props: {    payments: { type: Array }  }}</script>
<style lang="scss" scoped></style>

From within a Vue app, this is a straightforward component to use, right? For example:

在Vue应用程序中,这是一个易于使用的组件,对吗? 例如:

// app/javascript/App.vue
<template lang="html">  <div id="app>    <payments :payments="payments" />  </div></template>
<script>import Payments from './Payments.vue'
export default {  name: 'app',
components: { Payments },
data () {    return {      payments: [        { amount: 123.00 },        { amount: 124.00 }      ]    }  }</script>
<style lang="scss" scoped></style>

But what about using it in a Rails view?

但是在Rails视图中使用它呢?

(Solution)

So a solution for using the Payments.vue component in Rails looks like this:

因此,在Rails中使用Payments.vue组件的解决方案如下所示:

// app/views/payments/index.haml
.global-comp  = content_tag 'comp-wrapper', nil, data: { component: 'payments', props: { payments: @payments } }.to_json

Let’s break this element down.

让我们分解一下这个元素。

.global-comp is a div (with class “global-comp”) for mounting a super simple Vue instance. This Vue instance gives us a wrapper component to use called CompWrapper.vue (we’ll get to what CompWrapper is for in a minute).

.global-comp是用于挂载超简单Vue实例的div(类为“ global-comp”)。 这个Vue实例为我们提供了一个名为CompWrapper.vue的包装器组件(稍后我们将介绍CompWrapper的用途)。

Here is the Vue instance mounted to .global-comp:

这是安装到.global-comp的Vue实例:

// app/javascript/packs/global_comp.js
import Vue from 'vue/dist/vue.esm'import CompWrapper from './CompWrapper'
document.addEventListener('DOMContentLoaded', () => {  const app = new Vue({    components: { CompWrapper }  }).$mount('.global-comp')})

All this does is make the component (CompWrapper.vue) available to us within a div with the class global-comp.

所有这些操作就是使组件( CompWrapper.vue )在类中具有global-comp类的div可供我们使用。

If you are using Webpacker with Rails, you will need to include this pack within your layout somewhere before the closing body tag. For example:

如果您将Webpacker与Rails一起使用,则需要在封闭body标记之前的某个位置将此包包含在布局中。 例如:

// app/views/layouts/application.haml
...
= javascript_pack_tag "global_comp"
CompWrapper.vue (CompWrapper.vue)

This is the fun part. CompWrapper.vue allows us to pass:

这是有趣的部分。 CompWrapper.vue允许我们传递:

  1. The name of the component we want to use, for example, “payments”

    我们要使用的组件名称,例如“付款”
  2. The props we want to pass to it

    我们想要传递给它的道具

The whole purpose of this wrapper component is to allow us to pass Rails instance variables like @payments into our components as props without having to handle this from within each component like Payments.vue.

包装器组件的全部目的是使我们可以将@payments类的Rails实例变量作为@payments到我们的组件中,而不必从Payments.vue之类的每个组件中进行处理

So here is CompWrapper.vue:

所以这是CompWrapper.vue

// app/javascript/CompWrapper.vue
<template lang="html">  <component :is="data.component" v-bind="data.props"></component></template>
<script>import * as components from './components'
export default {  name: 'comp-wrapper',
components,
data () {    return {      data: {}    }  },
created() {    this.data = JSON.parse(this.$attrs.data)  }}</script>
<style lang="scss" scoped></style>

The first thing the CompWrapper component is doing is taking the data attributes you set on the element in the Rails view, parsing the JSON, and setting an internal Vue data attribute with the parsed data:

CompWrapper组件要做的第一件事是获取您在Rails视图中的元素上设置的数据属性,解析JSON,并使用解析的数据设置内部Vue数据属性:

created() {  this.data = JSON.parse(this.$attrs.data)}

with this.data set we can then use it to select the component we want to use and pass it the props we provided in our Rails view using a Vue dynamic component:

有了this.data集,我们可以使用它来选择我们要使用的组件,并使用Vue动态组件将我们在Rails视图中提供的道具传递给它:

<component :is="data.component" v-bind="data.props"></component>

And that’s it!

就是这样!

We can now use Vue components as they’re meant to be used, but from within our rails views. ?

现在,我们可以按原样使用Vue组件,但可以在rails视图中使用。 ?

翻译自: https://www.freecodecamp.org/news/how-to-pass-rails-instance-variables-into-vue-components-7fed2a14babf/

rails 共享变量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值