从 rails 渲染过程中为 Vue 模型设置值

Set value to Vue model from rails rendering process

我创建了一个完整的 rails 应用程序,但我添加了 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> a.k.a。 Vue 框架仅用于处理一些特定任务。其中一项任务是像这样控制范围输入组件:

_a_single_layout.html.erb

<div id="app">
  <h1>{{progress}}%</h1>
  <input type="range" min="0" max="100" v-model="progress">
</div>

application.js

let app = new Vue({
  el: "#app",
  data: {
    progress: 0
  }
})

我得到的是:

问题是如何在此处设置rails应用程序的当前存储值,同时将此值绑定到Vue模型。

我试过的:

<h1>{{progress = <%= @model.progress %>}}%</h1>

● 这实际上是按照我想要的方式分配值,但是范围输入卡住了。

<input type="range" min="0" max="100" v-bind:progress="<%= @model.progress %>">

● 这会将范围移动到其预期位置,但当我用鼠标移动它时停止刷新视图。

<input type="range" v-model="progress" v-bind:progress="<%= @model.progress %>">

● 两者都设置,v-modelv-bind忽略最后一个。

let app = new Vue({
  el: "#app",
  data: {
    progress: <%= @model.progress %>
  }
})

● 我也曾尝试在 javascript 端写入值,但这不是 rails.

的有效语法

● 我一直在寻找类似 v-on:load="progress = <%= @model.progress %>" 的东西,但似乎 v-on 没有任何加载事件处理程序。

以下是我在笔上试过的东西:https://codepen.io/alex3o0/pen/XWrLwwm

我只是采用了一种棘手的解决方案;我将我的 rails 模型变量设置为一个 Vue 模型变量,它得到 "stuck" 但是在创建的方法上(使用 setTimeout 延迟动作 ¯\_(ツ)_/¯)我将这个值重新分配给第二个完全免费的 Vue 模型变量:

_a_single_layout.html.erb

<div id="app">
  <span class="hide-me">{{real_value = <%= @model.progress %>}}</span><!-- this variable gets the value from the rails model but also gets "stuck" -->
  <h1>{{progress}}%</h1>
  <input type="range" min="0" max="100" v-model="progress"><!-- this variable will get its real value when the "created" method starts -->
</div>

application.js

let app = new Vue({
  el: "#app",
  data: {
    progress: 0,
    real_value: 0
  },
  created: function(){
    setTimeout(() => this.progress = this.real_value, 1000)
  }
})

顺便说一下,我仍在寻找 "correct" 解决方案。

解决办法是创建一个Vue组件。
然后你可以通过这个带有 props 的组件将你的 'rails' 数据传递给 Vue。您只需要先将其转换为 JSON 即可:

_a_single_layout.html.erb

<div id="app">
  <load-progress :progress="<%= @model.progress.to_json %>"></load-progress>
</div>

application.js

const LoadProgress = Vue.component('load-progress', {
  template: `
    <div>
      <p>{{ progress }}%</p>
      <input type="range" min="0" max="100" :value="progress">
    </div>`,
  props: ['progress']
})

const app = new Vue({
  el: '#app',
  components: { LoadProgress }
})