2017-02-15 14 views
1

У меня есть компонент, который создает меню выбора/выпадающего меню.Функция выбора по умолчанию не обновляется в DOM, даже если атрибут v-model обновляется

Существует вызов 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

Edit 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> 

Я надеюсь, что это поможет кому-то. Я собираюсь позволить Эвану вы об этом знаете, поскольку это похоже на то, что должно быть исправлено или, по крайней мере, отмечено в официальной документации.

Резюме:

Реквизит, используемый в блоке скрипта компоненты также должен быть представлены где-то в шаблоне компоненты, в противном случае может возникнуть некоторое неожиданное поведение.

ответ

0

Пропорция, которую я использую в блоке сценария, selectedOption, должна отображаться в шаблоне, даже если она там не используется.

Так что:

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

становится:

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

Теперь selected элемент успешно обновляет в DOM.

0

VueJS имеет специальную конфигурацию для v-model on custom components. В частности, компонент должен иметь опору value, которая выберет v-model от родителя. Вы затем this.$emit('input', newVal) об изменении, как вы уже настроили.

Я не уверен, где именно разбивка с вашим компонентом, но here is a working example. Возможно, вы просто слишком усложнили изменение выбранных данных. Если вы правильно настроили, вы можете просто исправить это изменение и позволить родительскому дескриптору фактически обновлять то, что назначено v-model. В примере я включил несколько кнопок для изменения выбранного var из родительского и компонентного, чтобы проиллюстрировать изменение var (parent) или испускание изменения (компонента).

+0

Как вы можете видеть в моем примере кода, я уже использую '$ emit' и' value' prop. Усложнение возникает, когда выбранное значение должно быть задано с помощью динамических данных в коде ... а не через пользователя, взаимодействующего с выпадающим списком. – Stephen

+0

Внутри компонента похоже, что вы используете 'v-model', а затем« обновленный »цикл жизненного цикла, чтобы испускать изменения, которые я считаю не оптимальными в этом случае. – Justin

+0

С точки зрения установки значения, посмотрите, что делают функции нажатия кнопки в jsfiddle, который я разместил. – Justin