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

时间:2018-10-09 21:33:11

标签: javascript html vuejs2 html-select v-model

在对某些类型的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>

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

当我启动Vue时,似乎您声明的v-Modal上的任何“选择”都会丢失其所选值。如the documentation中所述:

  

v-model将忽略初始值,选中或选定的属性   在任何表单元素上都可以找到。它将始终处理Vue实例数据   作为真理的源头您应在上声明初始值   在JavaScript方面,位于组件的data选项中。

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

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

2 个答案:

答案 0 :(得分:1)

要利用vue的反应系统,vue需要完全控制。因此,没有办法解决,您必须以某种方式通知vue这些默认值。

如果您是以html为中心的,那会有些尴尬:您必须选择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开头)。该组件将接收道具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 :(得分:0)

@ b0nyb0y的答案在技术上是正确的,但是由于它不能解决我的特定问题,我想我会在此处包括我的hacky解决方法,以供将来参考(仅适用于select):

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