如何将从父组件传递的道具推送到子组件中的数组?

How to push a prop passed from a parent component to an array in the child component?

我有 3 个组成部分。一个父组件和两个子组件。两个子组件是兄弟。

父组件

 <template>
  <div class="wrapper">
    <div class="main-content">

        <Modal :popupTitle="popupTitle" @addLocation="addLocation($event)"/>
        
        <BinInfo :newBinLocation="newBinLocation"/>

        <button data-bs-toggle="modal" data-bs-target="#staticBackdrop">Add new bin</button>
    </div>
  </div>  
 </template>

<script>


export default {
    data(){
      return{
        popupTitle:"Add New Bin Location",
        newBinLocation: '',
      }
   },
   methods:{
     addLocation(newBinLocation){
       this.newBinLocation = newBinLocation
     }
   },
  components:{
      Navigation,
      TopBtns,
      BinInfo,
  }
}
</script>


在一个子项中,即列表组件,我正在显示数组中的列表

列表组件

<template>
<div class="table-responsive">
    <h2>Bins - Location</h2>
    <h5 v-if="bins.length==0">There are no bin locations added</h5>
    <table class="table table-striped" v-if="bins.length > 0">
        <thead>
        <tr>
            <th scope="col">#</th>
            <th scope="col">Location</th>
            <th scope="col" class="text-end">Action</th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="(bin, index) in bins" :key="index">
            <th scope="row">{{index + 1}}</th>
            <td><input ref="inputField" type="text" :value="bin.binlocation" :disabled="bin.disabled" @change="editedLocation=$event.target.value"></td>
            <td class="text-end">
            <div class="action-btn">
                <button @click="btnEdit(index)"><fa icon="edit" /> Edit</button>
                <button @click="btnUpdate(index)"><fa icon="edit" /> Update</button>
                <button @click="btnDelete(index)"><fa icon="trash" /> Delete</button>
            </div>
            </td>
        </tr>
        </tbody>
    </table>
    <div class="btn-area">
        <router-link to="/bins">View More</router-link>
    </div>
</div>
{{newBinLocation}}

</template>

<script>
export default {
    data(){
        return{
            bins:[
                {
                    binlocation: '11 Garden Block, New City',
                    disabled: true
                },
                {
                    binlocation: 'Ali Towers, Lahore',
                    disabled: true
                },
                {
                    binlocation: 'The Mall Road',
                    disabled: true
                }
            ],
            editedLocation: null,
        }
    },
    props:['newBinLocation'],
    methods:{
        btnDelete(index){
           this.bins.splice(index, 1)
        },
        btnEdit(index){
         this.bins[index].disabled = !this.bins[index].disabled;
         this.editedLocation = this.bins[index].binlocation
         /*if(this.bins[index].disabled === false){
             console.log(this.$refs.inputField)
         }*/
        },
        btnUpdate(index){
           this.bins[index].binlocation = this.editedLocation
           this.bins[index].disabled = !this.bins[index].disabled
           console.log(this.bins[index].binlocation)
        },
        btnAdd(){
            let newLocation = {
                binlocation: this.newBinLocation,
                disabled: true
            }
            this.bins.push(newLocation)
        }
    },
}
</script>

<style scoped>
.table-responsive{
    margin-bottom:25px;
}
h2{margin:0 0 15px;}
.action-btn button{
    border:0;
    background:#003594;
    color:#fff;
    margin-left:15px;
    padding:3px 15px;
}
.action-btn button:hover{
    background:#3490dc
}
input{
    background-color:none;
    border:0;
    color:#000;
}
</style>

在第二个子组件中,我创建了一个模式,我用它来添加新列表。

模态组件

<template>
  <div class="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">{{popupTitle}}</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <p><input type="text" v-model="addBinLocation"></p>
      </div>
      <div class="modal-footer">
        <button @click="btnAdd" type="button" class="btn btn-primary">Add Location</button>
      </div>
    </div>
  </div>
</div>
</template>

<script>
export default {
    props:['popupTitle'],
    data(){
      return{
        addBinLocation: ''
      }
    },
    methods:{
      btnAdd(){
        this.$emit('addLocation', this.addBinLocation)
    }
  }
}
</script>

<style>

</style>

我可以添加和接收值,但如何将新道具添加到现有数组中,以便将其添加到列表中。

有一种方法可以在 Listing Component 中添加带有计算 属性 的 newBinLocation,但这不是最简洁的方法。

您在 Listing Component 中声明 bins 数组时出现架构错误。父组件应该是知道数据的组件。 Listing Component 仅用于打印列表。

您应该将 Parent Component 中的数组作为道具传递。这样 Listing Component 将很容易重复使用。

完成后,就可以轻松地向数组中添加新项了。

这是一个例子

父组件

 <template>
  <div class="wrapper">
    <div class="main-content">

        <Modal :popupTitle="popupTitle" @addLocation="addLocation($event)"/>
        
        <BinInfo :bins="bins"/> <-- You need to pass the array instead of newBinLocation -->

        <button data-bs-toggle="modal" data-bs-target="#staticBackdrop">Add new bin</button>
    </div>
  </div>  
 </template>

<script>


export default {
    data() {
      return {
        popupTitle:"Add New Bin Location",
        bins:[
                {
                    binlocation: '11 Garden Block, New City',
                    disabled: true
                },
                {
                    binlocation: 'Ali Towers, Lahore',
                    disabled: true
                },
                {
                    binlocation: 'The Mall Road',
                    disabled: true
                }
          ],
      }
   },
   methods:{
     addLocation(newBinLocation){
       this.bins.push(newBinLocation) // You just have to push the new value
     }
   },
  components:{
      Navigation,
      TopBtns,
      BinInfo,
  }
}
</script>