如何在 Bootstrap Vue 中向父级发送模态数据?

Posted

技术标签:

【中文标题】如何在 Bootstrap Vue 中向父级发送模态数据?【英文标题】:How to send modal data to parent in Bootstrap Vue? 【发布时间】:2021-03-23 08:06:32 【问题描述】:

我是 Vue 和 Bootstrap Vue 的新手。

我构建了一个使用 API 数据数组的表。此表有一个按钮,可在子组件中打开 <b-modal>。该模式具有三个字段,它们通过单击按钮将数据附加到表的数组中。然后表更新。到这里为止。

问题是:当我尝试从<b-modal> 推送更多信息时,我之前从<b-modal> 添加的信息被修改了——无论是在数组中还是在表中。 API带来的信息没有被修改。

怎么了?非常感谢。

Vue.component('modal', 
    props:['commodity_data'],
    template:/*html*/`
        <div>            
            <b-modal id="addModal" ref="modal" hide-footer title="Add Commodity">
                <b-form-group>
                    <label>
                    Hu Count
                        <b-form-input
                            id="hu_count"
                            v-model="new_row.hu_count"
                            >
                        </b-form-input>
                    </label>
                    <label>
                    Dimensions
                        <b-form-input
                            id="dimensions"
                            v-model="new_row.dimensions"
                            >
                        </b-form-input>
                    </label>
                    <label>
                    Weight
                        <b-form-input
                            id="weight"
                            v-model="new_row.weight"
                            >
                        </b-form-input>
                    </label>
                </b-form-group>

            <b-button variant="success" @click="addRow">Add Row</b-button> 
        </b-modal>

        </div>
    `,
    data()
        return
            new_row:
            
                dimensions: '',
                hu_count: '',
                weight: '',
            
        
    ,
    methods:
        addRow: function ()             
            this.commodity_data.push(this.new_row)
            this.$refs.modal.hide()
            console.log(this.commodity_data);
        
    
)

包含b-modal的表格代码:

Vue.component('commodity', 
    template: /*html*/`
    <div class="mx-auto commodity card">
            <div class="commodity__div-buttons">
                <div class="commodity__buttons">
                    <b-button variant="success" v-b-modal.addModal>Add Row</b-button> 
                    <b-button variant="danger" @click="deleteRows">Delete</b-button> 
                </div>
            </div>

        <b-table striped hover responsive :fields="fields" :items="commodity_data">

            <template #head(index)="data">
                <input type="checkbox" @click="selectAll" ref="checkAll">
            </template>

            <template #cell(index)="data">        
                <input type="checkbox" @click="selectRows(data.index)">
            </template> 

        </b-table>

        <modal id="addModal" :commodity_data="commodity_data"></modal>
        
    </div>
    `,
    data() 
        return 
            commodity_data: [],
            checkboxes: '',
            fields: [
                
                    key: 'index'
                ,
                
                    key: 'hu_count',
                    label: 'Hu Count'
                ,
                
                    key: 'dimensions',
                    label: 'Dimensions'
                ,
                
                    key: 'weight',
                    label: 'Weight'
                
            ]
        
    ,
    methods: 
        selectRows: function (e) 
            this.commodity_data[e].checked = !this.commodity_data[e].checked
        ,
        deleteRows: function () 
            for (let i = 0; i < this.commodity_data.length; i++) 
                if (this.commodity_data[i].checked) 
                    this.commodity_data.splice(i, 1)
                    i--
                
            
            this.checkboxes.forEach(element => 
                element.checked = false
            );
        ,
        selectAll: function () 
            this.commodity_data.forEach(element => 
                element.checked = !element.checked
            );

            if (this.$refs.checkAll.checked) 
                this.checkboxes.forEach(element => 
                    element.checked = true
                );
             else 
                this.checkboxes.forEach(element => 
                    element.checked = false
                );
            
        
    ,
    created: function () 
        let data = JSON.parse(sessionStorage.getItem('data_info'))
        this.commodity_data = data.commodity
        
    ,
    mounted()
        const table = document.querySelector('table')
        this.checkboxes = table.querySelectorAll('input')
    
)

【问题讨论】:

【参考方案1】:

有两个问题:1)我们应该在子组件中never modify props,2)添加数据时,每次添加的子数据都是相同的引用

固定孩子

而不是修改道具,$emit 一个带有克隆子数据的事件:

addRow() 
   this.$emit('add',  ...this.new_row );  
   this.$refs.modal.hide()

spread 运算符创建一个浅层副本。

修复父级

现在孩子发出一个父母应该监听的事件。在子标签上创建监听器:

<modal id="addModal" @add="addData" :commodity_data="commodity_data"></modal>

并创建处理程序方法(在父级中):

addData(data) 
   this.commodity_data.push(data);

【讨论】:

以上是关于如何在 Bootstrap Vue 中向父级发送模态数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何在角度应用程序中向父级添加类?

使用 vue.js 和 laravel 从子级向父级发送数据

如何在 Vue 中向父布局槽发出事件?

童工如何在Deno中向父进程发送消息?

在 Electron 中向父窗口发送消息

将 vue.js 组件子中的对象或值发送到父通信