简体   繁体   English

V-for中用于引导选择器的Vue.js子组件

[英]Vue.js child component for bootstrap selectpicker in v-for

I have a table where for each row the first <td> contains a select element. 我有一张表,其中每行的第一个<td>包含一个select元素。 The select element renders out of a child component, which uses bootstrap's selectpicker. select元素从子组件中渲染出来,该子组件使用引导程序的selectpicker。

Selectpicker.vue 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 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>

The component is registered separately in a globals file, and it is rendering fine. 该组件分别在globals文件中注册,并且呈现良好。 When a select element is changed in the table - A1 - I need all of the values in B1, C1, D1 etc to update. 当表格中的选择元素-A1发生更改时,我需要更新B1,C1,D1等中的所有值。 This isn't happening with what I have setup now. 我现在的设置不会发生这种情况。

Any help is very much appreciated. 很感谢任何形式的帮助。

Here is another instance of the selectpicker in a parent component. 这是父组件中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>

Simplify the Selectpicker.vue file 简化Selectpicker.vue文件

You don't need to do all this 'observe' stuff below. 您无需执行以下所有“观察”操作。 Just bind a value and let Vue do the observing. 只需绑定一个值,然后让Vue进行观察即可。 That's what it is good at . 就是擅长的 Remove all this: 删除所有这一切:

    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)
        }
    }

Make it into something like (notice the "observer" stuff code above was removed and two attributes were added to the template): 将其设置类似(注意,上面的“观察者”内容代码已删除,并且向模板中添加了两个属性):

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

Simple, yeah? 很简单,是吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM