默认 select 选项未在 DOM 中更新,即使 v-model 属性正在更新

Default select option is not being updated in DOM, even though the v-model attribute is updating

我有一个构建 select/dropdown 菜单的组件。

有一个 API 调用导致 collectionselectedOption 得到更新并成功构建下拉列表。

<!-- src/components/systems/SystemEdit.vue -->    
<custom-dropdown v-model="system.sensor_type" id="sensor_type" name="sensor_type" :collection="sensorTypeDropdown.collection" :firstOption="sensorTypeDropdown.firstOption" :selectedOption="sensorTypeDropdown.selected"></custom-dropdown>


<!-- src/components/CustomDropdown.vue -->
<template>
  <select v-model="selection" required="">
    <option v-show="firstOption" value="null">{{firstOption}}</option>
    <option v-for="item in collection" :value="item[1]">{{ item[0] }}</option>
  </select>
</template>

<script>
  export default {
    props: ['value', 'firstOption', 'collection', 'selectedOption'],
    name: 'customDropdown',
    data () {
      return {
        selection: null
      }
    },
    watch: {
      selection: function(sel) {
        this.selection = sel
        this.$emit('input',sel)
      }
    },
    updated: function() {
      if(this.selectedOption) {
        this.selection = this.selectedOption
      }
    }
  }
</script>

<style>
</style>

下拉输出如下所示:

<select required="required" id="sensor_type" name="sensor_type">
    <option value="null">Select sensor type...</option>
    <option value="sensor1">sensor1</option>
    <option value="sensor2">sensor2</option>
    <option value="sensor3">sensor3</option>
</select>

如果我设置了 selection: "sensor1" 数据属性,那么 sensor1 会如预期那样被选中。

相反,如果我更新 this.selection = this.selectedOptionthis.selection = "sensor1",那么它 不会 成为选定的选项......即使 console.log(this.selection) 确认改变。我已经尝试在 created 挂钩和其他地方设置它。如果我保存更改,下拉默认值会在热重载时成功设置。但是它初始化的第一次加载将不起作用。

如何让 this.selection = this.selectedOption 正确地反映在 DOM 中以显示该选项已被选中?

我正在使用 Vue 2.1.10

编辑 1:

仍然没有运气,现在采用这种方法:

data () {
  return {
    selection: this.setSelected()
  }
},
methods: {
  setSelected: function() {
    var sel = null
    if(this.selectedOption) {
      sel = this.selectedOption
    }
    console.log(sel)
    return sel
  }
}

即使 sel 输出 "sensor1" 并且 Vue 检查器确认 selection:"sensor1"

编辑 2:

我已经缩小了问题范围,但还没有找到解决方案。

methods: {
  setSelected: function() {
    var sel = null
    if(this.selectedOption) {
      sel = this.selectedOption
    }
    return sel
  }
}

它在 return sel 上失败了。

sel 未被视为字符串;我怀疑这是一个 Vue 错误。

作品:

return 'sensor1'

失败:

return sel

我已经尝试了所有这些变通办法(none 有效):

sel = String(this.selectedOption)
sel = (this.selectedOption).toString()
sel = new String(this.selectedOption)
sel = this.selectedOption+''
sel = 'sensor1'

这 "work" 的唯一方法是使用字符串文字,这对我来说毫无用处。

我难住了。

已解决

为了让它工作,我传递给组件的 selectedOption 属性必须在组件模板的某处 呈现,即使你没有在模板中使用它。

失败:

<select v-model="selection" required="">

作品:

<select v-model="selection" required="" :data-selected="selectedOption">

那个数据属性可以是:data-whatever…只要它在模板中的某处呈现。

这也有效:

<option v-show="!selectedOption" value="null">{{selectedOption}}</option>

<div :id="selectedOption"></div>

我希望这对某人有所帮助。我会让埃文知道这件事,因为它似乎应该被修复或至少在官方文档中注明。

总结:

组件脚本块中使用的道具也必须在组件模板中的某处呈现,否则可能会出现一些意外行为。

我在脚本块中使用的道具 selectedOption 需要在模板中呈现,即使它没有在那里使用。

所以这个:

<select v-model="selection" required="">

变成:

<select v-model="selection" required="" :data-selected="selectedOption">

现在 selected 项在 DOM 中成功更新。

VueJS 有针对 v-model on custom components 的特定配置。特别是该组件应该有一个 value 属性,它将从父组件中获取 v-model 。然后你 this.$emit('input', newVal) 像你配置的那样改变。

我不确定您的组件发生故障的确切位置,但 here is a working example。更改所选数据可能过于复杂。如果配置正确,您只需发出更改并让父级处理实际更新分配给 v-model 的内容。在示例中,我包含了一些按钮来更改父项和组件中的选定变量,以说明更改变量(父项)或发出更改(组件)。