在 VueJS 中是否可以用 v-model 绑定一些东西然后反弹到另一个 child?

In VueJS is it possible to bind something with v-model that is then rebound to another child?

我有一个应用程序,我正在为其创建一个自定义组件,它将输出 table 的单行。它包含一个数字字段 user-adjustable,因此 在该自定义组件中 我正在使用 quasar 框架 (q-numeric) 中的另一个自定义组件。我正在努力了解如何通过 2 个组件在 top-level 处绑定一个变量——也许不能直接完成,但我希望避免在中间组件中使用大量额外代码。到目前为止,从上到下看起来是这样的:

在 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,这会变异它。真的,我不想将 top-level 变量 numParticipants 绑定到 q-numeric - 是否可以在我的 config-item 组件中实现某种 'pass through'?或者我的组件是否需要拥有它自己的数据元素,它从 passed-in 属性初始化,并响应 q-numeric 进行更新?我知道我 可以 这样做,但我希望有一个更清洁的解决方案...

更新: 您可以通过根据道具进行可写计算来向下传播 v-model-能力(道具必须命名为 'value' ). get函数显然是returns的prop值; set 函数执行 $emit.

计算出的规格是完全固定的,所以我将其提取为常量。

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
          }
        }
      }
    }
  }
});
<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>

这就是我最终得到的 - 似乎是最简单的方法。当 'middle' 组件有效地承诺不更改模型但只想将其传递给 child.

时,我有点希望 Vue 有一种机制来隐藏它

基本上,我创建了一个中间数据元素 ivalue,并在 mounted() 事件中对其进行了初始化,并使用 child 的 input() 事件发出一个input()事件回parent.

<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>