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>

  <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 的任何“选择”似乎都会失去其选择的值。如文档中所述

v-model 将忽略在任何表单元素上找到的初始值、选中或选定属性。它将始终将 Vue 实例数据视为事实来源。您应该在组件的 data 选项内声明 JavaScript 端的初始值。

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

有没有更简单的方法来做到这一点?也许某种选项或标签我可以提供给 Vue 以“持久”从 HTML 控件的初始状态继承的值?

4

2 回答 2

1

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

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

正确的做法vue是完全由数据驱动,并根据数据构建 HTML。例如,如果您的表单有 2 个选择框,那么使用vue' 方式,您应该为所有options 定义数据,并使用这些数据从头开始生成这些元素(请注意,我在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将根据数据要求预先选择。您还可以在此代码框上看到一个工作示例

于 2018-10-10T19:04:47.803 回答
0

@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;
});
于 2018-10-10T23:05:17.280 回答