在组件中动态地将数据绑定到vue模型

时间:2016-11-04 15:59:22

标签: javascript html templates vue.js reactive-programming

我正在尝试创建一个简单的表单,接受用户对不同类型货币的输入。

这是一个(破碎的)小提琴,希望能够实现我想要做的事情: https://jsfiddle.net/4erk8yLj/7/

我希望我的组件将数据绑定到我的root vue实例,但我不确定我的v-model字符串是否允许。看看:

Vue.component('conversion-row', {
  props: ['currency', 'values'],
  template: '<div>{{currency}}:</div><div><input v-model="values[currency]></div><',
});

var vm = new Vue({
  el: "#app",
  data: {
    currencies: ['USD', 'BTC'],
    values: {
      'BTC': '',
      'USD': ''
    }
  }


});

模板:

<div id="app">
  <li>
    <conversion-row is li v-for="currency in currencies" v-bind:currency="currency">
    </conversion-row>
  </li>
</div>

解决这个问题的好方法是什么?

1 个答案:

答案 0 :(得分:2)

您可能需要纠正的一些事情:

首先,data属性必须是函数而不是对象。这允许每个实例在每次创建时重新计算数据,请参阅:

var vm = new Vue({
  el: "#app",
  data() {
    return {
      currencies: ['USD', 'BTC'],
      values: {
        'BTC': 'BTC Value',
        'USD': 'USD Value',
      },
    };
  }
});

其次,<conversion-row>没有values属性限制。以下是您可以做的事情:

<div id="app">
  <li v-for="currency in currencies">
    <conversion-row :currency="currency" :values="values"></conversion-row>
  </li>
</div>

最后,组件应始终以一个根元素(包装器)为目标,然后您可以根据需要嵌套多个子元素。更重要的是,您可以绑定v-model而不是使用value,这是将值传递给输入的正确方法(单向数据绑定),请检查以下内容:

Vue.component('conversion-row', {
  props: ['currency', 'values'],
  template: '<div>{{currency}}:<input type="text" :value="values[currency]"></div>'
});

如果您需要将values以及currency传递给conversion-row,我可以在此处进行更多改进,例如重新思考,但是我可以相当肯定你以后会弄明白的。

以上所有内容将使您的代码正常运行和执行,这是工作示例(您的分支):

这有帮助吗?

不确定您在使用v-model方面的目标是什么,但这里有一个工作v-model的例子(基于您的示例):

Vue.component('conversion-row', {
  props: ['currency', 'values'],
  template: '<div>{{currency}}:<input type="text" v-model="values[currency]"></div>'
});

以及相应的模板:

<div id="app">  
  <p><strong>USD Value:</strong> {{ values.USD }}</p>
  <p><strong>BTC Value:</strong> {{ values.BTC }}</p>

  <br>

  <li v-for="currency in currencies">
    <conversion-row :currency="currency" :values="values"></conversion-row>
  </li>
</div>

您可以在以下网址找到它: