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允許我們傳遞:
- The name of the component we want to use, for example, “payments” 我們要使用的組件名稱,例如“付款”
- 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 共享變量