Vue Input창 동적추가

하율찬·2023년 4월 20일
0

일과사전

목록 보기
2/4

1. 요청사항 테이블내에 input창 추가 (행 추가 X)

Input 창을 버튼을 누를때마다 1개씩 추가하거나 제거하는 기능을 요청받았습니다.
현재 이미 테이블 내에서 반복으로 데이터를 보여주고 있었고, 테이블 전체행이 추가되는 것이아니라 input 창만 추가되는 기능이 필요했습니다.

2-1. 트러블 슈팅 (행추가가 되어버림)

블로그 글에서 원하는 기능을 보았지만, 같은 방식으로 진행 했을시
원치않는 행들이 같이 늘어났습니다
이미 v-for 반복문으로 데이터를 받아서 보여주기때문에 제가 원하는 객체만 반복문을 한번 더 사용하여 이중 반복을 써야한다는 사실을 깨닫고 해당 객체부분만 반복문을 사용하였습니다.

<template>
<div>
 <template v-for="(item, index) in list"> 
 <tr :class="index%2==1 ? 'gray_row':''" v-bind:key="item.key" >
          <td :class="{need_to_send:item.ProgramOrderItem__status=='order'}" style="text-align:center;">{{item.id값}}</td>
          <td>{{item.날짜}}/{{item.날짜}}</td>
          <td>{{얻은 데이터}}</td>
          <td>{{item.데이터}}</td>
          ....
            <td v-if="item.ProgramOrderItem__status=='check'"><b-form-input v-model="item.ProgramOrderItem__log_code" placeholder="번호기입"></b-form-input>//반복을 한번더
         	 <b-button class="sort_button" variant="info" @click="removeInput(index)" >제거</b-button>
              <b-button class="sort_button" style="width:60%; margin: 0 10px;" variant="info" @click="addInput()" >추가</b-button>
            
            </td>
 </template> 
</div>
</template>

 data: function() {
    return {
      and_param:{},
      list:[],
      codes:[{ProgramOrderItem__log_code:''}],
    };
  },
  methods: {
    addInput(){
          this.list.push({ProgramOrderItem__log_code:''}); //list가아니라 codes로 수정헸어야했다.
    },
    removeInput(index){
      console.log(this.codes.length)
      if (this.codes.length==1){
        alert('더 이상 제거 할 수 없습니다.')
      }else{
        this.codes.splice(index, 1);
      }
    },

2-2 트러블슈팅 2 (인풋 창만추가 되었지만,하나의 인풋 창처럼 작동 데이터 바인딩 오류)


하지만, input창은 늘어났지만 하나의 인풋 창처럼 작동하게되어 데이터 바인딩이 잘못되었다는 것을 인지하고 내가 원하는 객체의 인풋에 바인딩을 하니 아래와 같이 잘 작동하였다.

3.해결


해당 배열인 codes를 보내면 됩니다 원래는 문자열이었는데 바꾸게되면서 [{}] 배열안 객체가 되었기때문에 api 수정을 해서 백엔드와 통신하게되면 마무리가 됩니다.

<template>
<div>
 <template v-for="(item, index) in list"> 
 <tr :class="index%2==1 ? 'gray_row':''" v-bind:key="item.key" >
          <td :class="{need_to_send:item.ProgramOrderItem__status=='order'}" style="text-align:center;">{{item.id값}}</td>
          <td>{{item.날짜}}/{{item.날짜}}</td>
          <td>{{얻은 데이터}}</td>
          <td>{{item.데이터}}</td>
          ....
            <td v-if="item.ProgramOrderItem__status=='check'">
			  <b-form-input v- <div style="display: flex; flex-direction: column; justify-content: center; align-items: center;">
              <div v-for="(code,index) in codes" :key="index" style="display: flex; flex-direction: row; margin: 5px;"> // 인풋만 한번 더 반복
              <b-form-input style="width: 100%; font-size: 13px; padding-left: 1px;" v-model="code.ProgramOrderItem__log_code" placeholder="번호 기입"/>
            <div style="display: flex; flex-direction: column; justify-content: center; align-items: center;" >
            <b-button class="sort_button" variant="info" @click="removeInput(index)" >제거</b-button>
            </div>
            </div>
            <b-button class="sort_button" style="width:60%; margin: 0 10px;" variant="info" @click="addInput()" >추가</b-button>
            </div>
         
          </td>
 </template> 
</div>
</template>

 data: function() {
    return {
      and_param:{},
      list:[],
      codes:[{ProgramOrderItem__log_code:''}],
    };
  },
  methods: {
    addInput(){
          this.codes.push({ProgramOrderItem__log_code:''}); 
    },
    removeInput(index){
      console.log(this.codes.length)
      if (this.codes.length==1){
        alert('더 이상 제거 할 수 없습니다.')
      }else{
        this.codes.splice(index, 1);
      }
    },

참고 블로그

https://aspdotnet.tistory.com/1978 (vue 인풋창추가)
https://aspdotnet.tistory.com/1979 (예시 및 구조이해)

profile
함께 일하고 싶어지는 동료가 되기를 원하는 프론트엔드 개발자입니다.

0개의 댓글