【问题标题】:How to push a prop passed from a parent component to an array in the child component?如何将从父组件传递的道具推送到子组件中的数组?
【发布时间】:2021-12-07 05:07:43
【问题描述】:

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

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

【问题讨论】:

  • how can I add the new prop into the existing array so that it is added in the list. 是什么意思?向数组添加道具?
  • 我们错过了一些上下文。可以分享一下数组的代码吗?
  • 您也可以发布模板吗?因为通常你会在父组件中监听发出的事件,然后更新父组件中的数组
  • 您的父组件需要有一个内部数组,您将 push 新项目放入其中,然后将其用作列表组件上的道具,然后可以迭代此数组中的项目。
  • 这个包含现有数据的数组应该只在父数组中,这是你推送新项目的数组。所以孩子只有这个数组作为道具。

标签: arrays vue.js vue-component vuejs3


【解决方案1】:

有一种方法可以在 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>

【讨论】:

    猜你喜欢
    • 2020-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-25
    • 1970-01-01
    相关资源
    最近更新 更多