代码之家  ›  专栏  ›  技术社区  ›  lukas_o

“透明”包装输入组件中的Vue双向绑定

  •  1
  • lukas_o  · 技术社区  · 6 年前

    我正在给一个小盒子写一个小包装 <input> 组件。 我在看文件 tutorial .

    不过,我有双向绑定的问题。 我希望我的组件与 v-model . 绑定似乎可以很好地更新值,但是当我更改值本身时,组件不会更新。我也有 read about transparent wrappers ,这似乎是我的问题。

    简单示例:

    <template id="numInput" :v-on="listeners">
      <div>
        <!-- note the div here, it works without, but that's not what I want -->
        <input ref:inp type="number" :value="num" @input="updateSelf($event.target.value)" @blur="reset" :class="{rc: isNegative}" />
      </div>
    </template>
    

    您可以找到完整的代码示例 here .

    绑定是单向的(修改文本输入)。但是输入组件不会以另一种方式更新(示例中的button klick)

    欢迎任何帮助!

    2 回复  |  直到 6 年前
        1
  •  1
  •   Decade Moon    6 年前

    自定义输入组件应该是无状态的(除非您有理由不这样做);这意味着组件的值应该由属性而不是本地状态(数据)提供。你的 <num-input> value 所需的道具 v-model

    您还可以设置 inheritAttrs $attrs 因为您已经将输入元素包装在一个div中了。

    Vue.component('num-input', {
      template: '#numInput',
      inheritAttrs: false,
      props: ['value'],
      computed: {
        isNegative() {
          return this.value < 0;
        },
      },
      methods: {
        onInput(e) {
          // You can conditionally do this after validation
          this.$emit('input', e.target.value);
        },
        onBlur() {
          if (this.isNegative) {
            this.$emit('input', 0);
          }
        },
      },
    });
    
    new Vue({
      el: '#app',
      data: {
        num: 0,
      },
    });
    .negative { color: red; }
    <script src="https://rawgit.com/vuejs/vue/dev/dist/vue.js"></script>
    
    <div id="app">
      <num-input v-model="num"></num-input>
      <button @click="num++">+1</button>
      <p>{{ num }}</p>
    </div>
    
    <template id="numInput">
      <div>
        <input type="number" :value="value" @input="onInput" @blur="onBlur" :class="{ negative: isNegative }" v-bind="$attrs">
      </div>
    </template>

    我没有强制 input 事件到一个数字(它是一个字符串),但我将把这个留给你。

        2
  •  0
  •   peter.edwards    6 年前

    这里有几个地方出了问题,但最基本的是在代码中混合了nom和num。我对你的组件做了一点修改,把num数据变成了一个属性,然后在你的主应用程序中绑定到它。

    这是你修改过的代码。。。

    Vue.config.devtools = true;
    
    // global component registration
    Vue.component('num-input', {
      template: '#numInput', 
      props: ['value'],
      computed: {
        isNegative: function() {
          console.log('num: ' + this.value)
          return this.value < 0;
        },
        listeners: function () {
          return this.$listeners;
        },
      },
      methods: {  
        reset () {
          if (this.isNegative) {
            this.$emit('input', 0)        
          }
        }
      },
    });
    
     new Vue({
       el: '#container',
       data: {
         num: 0,
       },
       methods: {
         increaseBy1() {
           this.num++;
           console.log("increased by 1");
         },
       },
     });
    

    为了查看代码和html绑定,我分叉了你的代码笔,它可以在。。。

    https://codepen.io/peterpde/pen/BOVQzg