首页 文章

Vue V模型启动损失选择选择

提问于
浏览
2

我在某些类型的html元素上初始化Vue时遇到问题,请看下面的代码:

new Vue({
  el: '#app',
  data: {
    test: ''
  }
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  Without Vue:
  <!-- Non-Vue select defaults to selected value -->
  <select>
    <option>1</option>
    <option selected>2</option>
    <option>3</option>
  </select>

  

With Vue: <!-- Vue enabled list loses selection --> <select v-model="test"> <option>1</option> <option selected>2</option> <option>3</option> </select> </div>

当我启动Vue时,似乎任何"selects"你声明v-Modal会失去他们选择的值 . 这与the documentation中描述的一样:

v-model将忽略在任何表单元素上找到的初始值,已检查或选定的属性 . 它总是将Vue实例数据视为真实的来源 . 您应该在组件的数据选项内的JavaScript端声明初始值 .

现在我可以这样做,但是对于每个选择我现在需要在Vue之外写一些JS来填充/重新填充选择默认值(通过填充“data”属性,或者在Vue减速后重新选择先前选择的值) .

有更简单的方法吗?也许某种选项或标签我可以向Vue提供“持久”从HTML控件的初始状态继承的值?

2 回答

  • 0

    为了利用 vue 的反应系统, vue 需要完全控制 . 所以没有办法绕过它,你必须以某种方式通知 vue 这些默认值 .

    如果你有点尴尬:你必须选择 dom 元素来找到它的默认值并将其重新设置为 vue . 这是有效的,但它会是单一的 .

    vue 中的正确方法是完全数据驱动,并根据数据构建HTML . 例如,如果您的表单有2个选择框,那么使用 vue 的方式,您应该为所有 option 定义数据,并使用这些数据从头开始生成这些元素(请注意我在这里使用 Single File Component 格式):

    <template>
      <div>
        <Select :items="list1"/>
        <Select :items="list2"/>
      </div>
    </template>
    
    <script>
    import Select from './components/Select.vue';
    
    export default {
      data() {
        return {
          list1: [
            { id: 1, name: "spoon" },
            { id: 2, name: "fork", preselect: true },
            { id: 3, name: "knife" }
          ],
          list2: [
            { id: 4, name: "macbook" },
            { id: 5, name: "dell" },
            { id: 6, name: "lenovo", preselect: true }
          ]
        };
      },
      components: { Select }
    };
    </script>
    

    并且,这是 <Select> 组件的代码(请注意,这是一个自定义Vue组件,因为它以大写 S 开头) . 该组件将收到prop items ,并自动计算给定项目中的选定值:

    <template>
      <select v-model="selected">
        <option 
          v-for="item of items"
          :key="item.id"
          :value="item.id">
            {{ item.name }}
        </option>
      </select>
    </template>
    
    <script>
    export default {
      props: ["items"],
      data() {
        return {
          // pre-select item from 'items'
          selected: this.items.filter(item => item.preselect)[0].id
        };
      }
    };
    </script>
    

    完成后,将根据数据指示预先选择项目 fork 和项目 lenovo . 您还可以在此codesandbox上看到一个有效的示例 .

  • 1

    @ b0nyb0y答案在技术上是正确的,但由于它没有解决我的具体问题,我想我会在这里包括我的hacky解决方法以供将来参考(仅适用于选择):

    var itemsToRestore = [];
    $('select[v-model]').each(function (index, value) {
        itemsToRestore.push({
            vModelProperty: $(value).attr("v-model"),
            selectedValue: $(value).val()
        });
    });
    
    var thisVue = new Vue({
        //Put your vue code here
    });
    
    itemsToRestore.forEach(function (value) {
        thisVue[value.vModelProperty] = value.selectedValue;
    });
    

相关问题