代码之家  ›  专栏  ›  技术社区  ›  David Thomas

如何使用Vue根据选中的复选框修改输入中的字符串?

  •  0
  • David Thomas  · 技术社区  · 6 年前

    昨天,在写这个问题的时候,我在YouTube上看到了一个简单、简短的Vue演示,在那之前不久,我还写了一篇文章 an answer this question .

    在它中,OP要求由 1 0 <input type="checkbox"> 元素,并根据这些元素的价值 checked (对于 1. 0 ). 在YouTube视频之后,我突然想到,这可以通过Vue生成:

    new Vue({
      el: 'div>form',
      data: {
        checkedStates: [
          [1, 0, 0, 1],
          [0, 0, 1, 1],
        ],
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
    <div>
      <form>
        <div v-for="(state, index) in checkedStates" class="form-group">
          <label class="control-label" :for=`group${index}States`>Sequence of on/off:</label>
          <input :id=`group${index}States` type="text" :value="state.join('')" class="myCars">
          <ul>
            <li v-for="entry in state">
              <label>
              <input type="checkbox" :name=`group${index}` :checked="entry === 1">
            </label>
            </li>
          </ul>
        </div>
      </form>
    </div>

    JS Fiddle demo .

    正如所料,这是相对简单的。

    然而,OP随后在对另一个答案的评论中问道,是否有可能更新 <input type="text"> 基于与复选框交互的用户的元素。到目前为止,我对Vue的体验还不到24小时。

    我最初的假设是我应该使用:

    <input type="checkbox" :name=`group${index}` :checked="entry === 1" @change="state">
    

    新Vue({
    el:'div>表格',
    检查状态:[
    [1, 0, 0, 1],
    ],
    }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
    <div>
      <form>
        <div v-for="(state, index) in checkedStates" class="form-group">
          <label class="control-label" :for=`group${index}States`>Sequence of on/off:</label>
          <input :id=`group${index}States` type="text" :value="state.join('')" class="myCars">
          <ul>
            <li v-for="entry in state">
              <label>
              <input type="checkbox" :name=`group${index}` :checked="entry === 1" @change="state">
            </label>
            </li>
          </ul>
        </div>
      </form>
    </div>

    vue.min.js:6 Uncaught TypeError: n[r].apply is not a function
      at i (vue.min.js:6)
      at HTMLInputElement.Rr.t._withTask.o._withTask (vue.min.js:6)
    

    (Chromium 70.x,Ubuntu 18.04)

    这个假设是基于一个错误的(显然)信念,即 state 事件处理程序的数据将更新该数据。

    显然,事件处理程序需要一个函数。因此,我修改了我的方法:

    <input type="checkbox" :name=`group${index}` :checked="entry === 1" @change="updateState()">
    

    new Vue({
      el: 'div>form',
      data: {
        checkedStates: [
          [1, 0, 0, 1],
          [0, 0, 1, 1],
        ],
      },
      methods: {
        updateState(){
          console.log(this.checkedStates);
        }
      },
    });
    

    这是一个验证步骤,以确保函数调用正常工作,这就是为什么它除了 console.log() ; 在这一点上,我意识到我可以访问 checkedStates 数组,但我不知道如何确定哪些嵌套数组应该更新。

    最终,我使用了散落在整个HTML和函数调用中的各种索引,结果是:

    new Vue({
      el: 'div>form',
      data: {
        checkedStates: [
          [1, 0, 0, 1],
          [0, 0, 1, 1],
        ],
      },
      methods: {
        updateState(i,n) {
          console.log(this.checkedStates[i][n]);
        }
      },
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
    <div>
      <form>
        <div v-for="(state, stateIndex) in checkedStates" class="form-group">
          <label class="control-label" :for=`group${stateIndex}States`>Sequence of on/off:</label>
          <input :id=`group${stateIndex}States` type="text" :value="state.join('')" class="myCars">
          <ul>
            <li v-for="(entry, entryIndex) in state">
              <label>
              <input type="checkbox" :name=`group${stateIndex}` :checked="entry === 1" @change="updateState(stateIndex, entryIndex)" v-model="entry">
            </label>
            </li>
          </ul>
        </div>
      </form>
    </div>

    这个 中的行 updateState() (选中)或 (未选中)。

    相配的 ,一个可怕的烂摊子;这让我相信我没有正确看待这个问题。

    Vue文档( https://vuejs.org/v2/guide/forms.html#Checkbox ) 似乎 建议使用 v-model="entry"

    <input type="checkbox" :name=`group${stateIndex}` :checked="entry === 1" @change="updateState(stateIndex, entryIndex)" v-model="entry">
    

    但是上面已经用过了,虽然它看起来不会产生任何错误,但是它也不会更新 entry 阵列;在这种情况下,对该数组的更新似乎会/应该自动反映在 <input> 元素。

    因此,我的问题可能是基于有缺陷的假设以及对Vue完全缺乏经验。

    1. 中的文本字符串 <输入> ,来源于 检查状态 的数组 data 对象并选中/取消选中 <输入type=“checkbox”> 元素,以及
    2. <输入> 是否更新以反映用户选中/取消选中已创建的复选框元素?
    1 回复  |  直到 6 年前
        1
  •  2
  •   David Thomas    6 年前

    你的逻辑是正确的,你的方向是正确的。你说的唯一的问题是你对Vue不熟悉。稍加修改就可以让它工作了。。

    new Vue({
      el: 'div>form',
      data: {
        checkedStates: [
          [1, 0, 0, 1],
          [0, 0, 1, 1],
        ],
      },
      methods: {
        updateState(state, index, event) {
          this.$set(state, index, event.target.checked ? 1 : 0)
        }
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
    <div>
      <form>
        <div v-for="(state, index) in checkedStates" class="form-group">
          <label class="control-label" :for=`group${index}States`>Sequence of on/off:</label>
          <input :id=`group${index}States` type="text" :value="state.join('')" class="myCars">
          <ul>
            <li v-for="(entry, entryIndex) in state">
              <label>
              <input type="checkbox" :name=`group${index}` :checked="entry === 1" @change="updateState(state, entryIndex, $event)">
              </label>
            </li>
          </ul>
        </div>
      </form>
    </div>

    JSFiddle

    解释(来自评论):

    在Vue中,可以使用 $event keyword custom events $event 将自动作为唯一参数传递。

    Vue can't detect modifications to an array when you directly access its elements Vue.set (或其别名) vm.$set )保持反应性