Vue V-Model 启动损失选择 Selection

Vue V-Model Initiation Losses Selects Selection

我在某些类型的 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 时,似乎任何 "selects" 你声明的 v-Modal 都失去了它们的 selected 值。如 the documentation:

中所述

v-model will ignore the initial value, checked or selected attributes found on any form elements. It will always treat the Vue instance data as the source of truth. You should declare the initial value on the JavaScript side, inside the data option of your component.

现在我可以做到这一点,但是对于每个 select 我现在需要在 Vue 之外编写一些 JS 到 populate/repopulate select 的默认值(通过填充"data" 属性,或重新select 之前 selected 值 post Vue 减速)。

有更简单的方法吗?也许我可以将某种选项或标签提供给 Vue 以从 HTML 控件的初始状态继承的 "persist" 值?

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

如果你以 html 为中心,那么它会有点尴尬:你必须 select dom 元素找到它的默认值并将其设置回vue。那行得通,但会很单调。

vue的正确做法是完全数据驱动,根据数据构建HTML。例如,如果您的表单有 2 个 select 框,那么使用 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,并根据给定的项目自动计算 selected 值:

<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 将根据数据指示预先 select 编辑。您还可以在 codesandbox.

上看到一个工作示例

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