默认 select 选项未在 DOM 中更新,即使 v-model 属性正在更新
Default select option is not being updated in DOM, even though the v-model attribute is updating
我有一个构建 select/dropdown 菜单的组件。
有一个 API 调用导致 collection
和 selectedOption
得到更新并成功构建下拉列表。
<!-- 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.selectedOption
或 this.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
的内容。在示例中,我包含了一些按钮来更改父项和组件中的选定变量,以说明更改变量(父项)或发出更改(组件)。
我有一个构建 select/dropdown 菜单的组件。
有一个 API 调用导致 collection
和 selectedOption
得到更新并成功构建下拉列表。
<!-- 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.selectedOption
或 this.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
的内容。在示例中,我包含了一些按钮来更改父项和组件中的选定变量,以说明更改变量(父项)或发出更改(组件)。