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

Posted

技术标签:

【中文标题】DOM 中未更新默认选择选项,即使 v-model 属性正在更新【英文标题】:Default select option is not being updated in DOM, even though the v-model attribute is updating 【发布时间】:2017-07-04 17:55:59 【问题描述】:

我有一个构建选择/下拉菜单的组件。

有一个 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

我已经尝试了所有这些解决方法(它们都不起作用):

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

这将“工作”的唯一方法是如果我使用字符串文字,这对我来说没用。

我被难住了。

已解决

为了使其工作,我传递给组件的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>

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

总结:

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

【问题讨论】:

【参考方案1】:

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

所以这个:

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

变成:

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

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

【讨论】:

【参考方案2】:

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

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

【讨论】:

正如您在我的代码示例中看到的,我已经在使用 $emitvalue 属性。当需要通过代码中的动态数据设置所选值而不是通过用户与下拉列表进行交互时,并发症。 span> 在组件中,您似乎使用v-model,然后使用updated 生命周期挂钩来发出更改,我认为这在这种情况下不是最佳选择。 在设置值方面,看看我贴的jsfiddle中的按钮点击功能在做什么。 我现在明白你的意思了。感谢您的代码示例。所以我稍微重构了我的代码,以便更充分地使用emit……但我最初的问题和解决方案保持不变:我仍然必须在模板中渲染selectedOption,以便在脚本块中使用该道具。 我不确定selectedOption 的原因。为什么不直接使用发射或直接在父级中设置v-model 的实际值?

以上是关于DOM 中未更新默认选择选项,即使 v-model 属性正在更新的主要内容,如果未能解决你的问题,请参考以下文章

即使在 Java 中未选中 Systems Daylight 选项,也始终使用 Java 中的夏令时获取时区

如何更改 iOS 7 中未选择的标签栏项目的颜色?

Firebase 选项中未定义存储桶。将个人资料照片更新到 Firebase

由于 v-model,Vue js 选择选项未出现

vue不常用到的v-model修饰符

在 jQuery mobile 中未选择选项卡时禁用表单输入