在VueJS中,是否可以将某些东西与v-model绑定,然后又反弹给另一个孩子?

时间:2017-04-25 09:13:15

标签: vue.js custom-component

我有一个应用程序,我正在创建一个自定义组件,它将输出一行表格。它包含一个用户可调的数字字段,因此在该自定义组件中我正在使用quasar框架中的另一个自定义组件(q-numeric)。我很难看到如何通过2个组件将顶级变量绑定到顶层 - 也许它无法直接完成,但我希望避免在中间组件中添加大量额外代码。到目前为止它从上到下看起来像这样:

在App.vue模板中,我有这样的行:

<config-item v-model="numParticipants">Number of Participants</config-item>

ConfigItem.vue,如下所示:

<template>
  <tr>
    <td class="text-right"><slot></slot></td>
    <td class="text-right">
      <q-numeric
        v-model="value"
        :min="min"
        :max="max"
        :step="step"
        @input="$emit('input', value)"
      ></q-numeric>
    </td>
  </tr>
</template>

<script>
  export default {
    props: {
      label: String,
      value: Number,
      min: {
        type: Number,
        default: 1
      },
      max: {
        type: Number,
        default: 1000
      },
      step: {
        type: Number,
        default: 1
      }
    }
  }
</script>

但当然这不起作用,因为我现在将属性 value绑定到q-numeric,这会使其变异。真的,我不想将顶级变量numParticipants绑定到q-numeric - 是否有可能在我的config-item组件中实现某种“传递”?或者我的组件是否需要拥有它自己的数据元素,它从传入的属性初始化,并更新以响应q-numeric?我知道我可以这样做,但我希望有一个更清洁的解决方案...

2 个答案:

答案 0 :(得分:4)

更新:您可以通过根据道具计算可写的(支柱必须命名为&#39;值&#39;),将v-model - 能力传播到层次结构中。 get函数显然返回prop值; set函数执行$emit

计算出的规范是完全固定的,所以我把它作为常量提取出来。

&#13;
&#13;
const vModelComputed = {
  get() {
    return this.value;
  },
  set(newValue) {
    this.$emit('input', newValue);
  }
};

new Vue({
  el: '#app',
  data: {
    numParticipants: 1
  },
  components: {
    middleComponent: {
      props: ['value'],
      template: '<div>Value: {{value}} <q-numeric v-model="localValue"></q-numeric></div>',
      computed: {
        localValue: vModelComputed
      },
      components: {
        qNumeric: {
          props: ['value'],
          template: '<div><input v-model="localValue" type="number"> inner value: {{value}}</div>',
          computed: {
            localValue: vModelComputed
          }
        }
      }
    }
  }
});
&#13;
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.min.js"></script>
<div id="app">
  Participants: {{numParticipants}}
  <middle-component v-model="numParticipants"></middle-component>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

这就是我最终的结果 - 似乎是最简单的方法。我有点希望当“中间”组件有效地承诺不改变模型时,Vue会有一个机制来隐藏它,但只是想把它交给一个孩子。

基本上,我创建了一个中间数据元素ivalue,并在mounted()事件中初始化它,并使用子节点的input()事件发出input()事件回到父母那里。

<template>
  <tr>
    <td class="text-right"><slot></slot></td>
    <td class="text-right">
      <q-numeric
        v-model="ivalue"
        :min="min"
        :max="max"
        :step="step"
        @input="$emit('input', ivalue)"
      ></q-numeric>
    </td>
  </tr>
</template>

<script>
  export default {
    data: () => ({
      ivalue: 0
    }),
    mounted () {
      this.ivalue = this.value
    },
    props: {
      label: String,
      value: Number,
      min: {
        type: Number,
        default: 1
      },
      max: {
        type: Number,
        default: 250000
      },
      step: {
        type: Number,
        default: 1
      }
    }
  }
</script>