Дочерний компонент Vue.js для селектора начальной загрузки в v-for

У меня есть таблица, в которой для каждой строки первый <td> содержит элемент выбора. Элемент select отображается из дочернего компонента, который использует selectpicker начальной загрузки.

Selectpicker.vue

<template>
    <div class='select-picker'>
        <select ref='selectpicker'>
            <slot></slot>
        </select>
    </div>
</template>

<script>
    export default {
        props: {
            initVal: [String,Object],
            default: ''
        },
        data(){
            return {
            }
        },
        mounted(){
            var selectpicker = $(this.$refs.selectpicker)
            this.selectpicker_dom_ref = selectpicker.selectpicker() // initialize

            this.selectpicker_dom_ref.selectpicker('val', this.initVal) // set initial value

            // Create the observer
            this.observer = new MutationObserver(() => { this.selectpicker_dom_ref.selectpicker('refresh') })

            // Setup the observer
            this.observer.observe(this.$refs.selectpicker, {childList: true})

            this.selectpicker_dom_ref.on('changed.bs.select', val => this.$emit('change', val))

        },
        watch: {
            value: function(val){
                this.selectpicker_dom_ref.selectpicker('val', val)
            }
        }
    }
</script>

ParentComponent.vue

<template>
    <table>
    <tr 
        v-for="(item, index) in rows" 
        :key="item.row_id">
            <td>
                <selectpicker 
                    v-model="item.item_id" 
                    :initVal="item.item_id">
                        <option 
                            v-for="opt in opts" 
                            :key="opt.item_id" 
                            :value="opt.item_id">
                            {{opt.name}}
                        </option>
                </selectpicker>
            </td>
            <td 
                v-for="column in columns" 
                :key="column">
                {{getOptById(item.item_id)[column]}}
            </td>
    </tr>
    </table>
</template>

<script>
export default {
    data() {
        return {
            columns: ['a', 'b', 'c', 'd']
            opts: [{'item_id':'123', 'name': 'xyz', 'a': 'aVal', 'b': 'bVal', 'c': 'cVal', 'd': 'dVal'}], // every selectpicker has the same options, every option has values corresponding to each column
            rows: [{'row_id': 'row1', 'item_id': '123'}],
        }
    },

    mounted() {
        const $el = $(this.$el)
        const self = this
    },

    methods: {
        getOptById(item_id) {
            return _.find(this.opts, {
                item_id
            }) || {}
        },
        updateRows(){
            _.each(this.rows, (item, index) => {
                item.row_order = index
            })
        }
    },

    watch: {
        rows: function(value, old_value) {
            this.updateRows()
        }
    }
}

</script>

Компонент регистрируется отдельно в глобальном файле и нормально отображается. Когда выбранный элемент изменяется в таблице - A1 - мне нужно обновить все значения в B1, C1, D1 и т.д. Это не происходит с тем, что я установил сейчас.

Любая помощь очень ценится.

Вот еще один экземпляр selectpicker в родительском компоненте.

<selectpicker
    class="bgs-location"
    @change="handleLocationSelect">
        <optgroup
            v-for="(locationGroup, groupName) in locationsByGroup"
            :key="groupName"
            :label="groupName">
                <option
                    v-for="location in locationGroup"
                    :key="location.guid"
                    :value="JSON.stringify(location)">
                    {{location.name}}
            </option>
        </optgroup>
    </selectpicker>

person Community    schedule 07.03.2018    source источник


Ответы (1)


Упростите файл Selectpicker.vue

Вам не нужно делать все эти «наблюдательные» вещи ниже. Просто привяжите значение и позвольте Vue наблюдать за ним. Это то, в чем он хорош. Удалить все это:

    mounted(){
        var selectpicker = $(this.$refs.selectpicker)
        this.selectpicker_dom_ref = selectpicker.selectpicker() // initialize

        this.selectpicker_dom_ref.selectpicker('val', this.initVal) // set initial value

        // Create the observer
        this.observer = new MutationObserver(() => { this.selectpicker_dom_ref.selectpicker('refresh') })

        // Setup the observer
        this.observer.observe(this.$refs.selectpicker, {childList: true})

        this.selectpicker_dom_ref.on('changed.bs.select', val => this.$emit('change', val))

    },
    watch: {
        value: function(val){
            this.selectpicker_dom_ref.selectpicker('val', val)
        }
    }

Превратите его в что-то вроде (обратите внимание, что приведенный выше код «наблюдателя» был удален, а в шаблон были добавлены два атрибута):

<template>
    <div class='select-picker'>
        <select ref='selectpicker' :value="initVal" @change="$emit('input', $event.target.value)">
            <slot></slot>
        </select>
    </div>
</template>

<script>
    export default {
        props: {
            initVal: [String,Object],
            default: ''
        },
        mounted(){
            $(this.$refs.selectpicker).selectpicker() // initialize
        }
    }
</script>

Просто, да?

person acdcjunior    schedule 07.03.2018
comment
по какой-то причине он не хочет отображать параметры родительского компонента после упрощения дочернего компонента. Привязано ли :value к реквизиту по умолчанию, переданному в... edit: есть некоторая разница в том, что прикреплено к ‹selectpicker› в разных родительских компонентах. (см. новый код) - person ; 07.03.2018