본문으로 바로가기

Vuejs와 Bootstrap Vue를 사용하면서 여러 개의 text입력을 배열 처리하려고 하는데 Bootstrap Vue에서 제공되는 컴포넌트에서는 배열 처리를 지원하지 않습니다. 본 포스트에서는 여러 개의 입력 양식을 배열로 처리하는 방법에 대해서 설명합니다. 추가적으로 key, value 기반의 map 형태 처리 방법도 설명합니다.

 

예제는 다음과 같이 구성하였습니다.

입력양식 배열 사용 예제

 

 

여러 개의 입력을 배열로 처리하기

입력값 처리 변수 추가하기

export default {
  name: 'Form',
  components: {
  },
  props : {
  },
  data () {
    return {
      multiple_input_array: "",          // 값 추가를 위한 입력양식의 값
      multiple_input_array_list : [],    // 배열처리된 입력양식의 값

      details : {},         // 입력양식의 현재 데이터
      origin : {},          // 입력양식의 기본 데이터(리셋 버튼클릭시 초기화될 값)
      defaults : {          // 기본값
        multiple_input_array_form : "array1,array2,array3",
      }
    }
  },
...(이하생략)...

1차원 입력값을 배열로 변환하기

초기 데이터를 화면에 맞게 데이터를 변환처리합니다. 초기 데이터는 관계형 데이터베이스에서 전달받는 데이터 형태(JSON과 같은 다중 깊이 MAP이 아닌 1차원 MAP)입니다.

export default {
  name: 'Form',
  data () {
......(중간생략)......
  },
  created() {
    this.setData(this.defaults);
  },
  methods : {
    setData(data) {
      this.origin = Object.assign({}, data);


      this.multiple_input_array_list = [];
      if(this.origin.multiple_input_array_form) {
        const arr = this.origin.multiple_input_array_form.split(",");
        arr.forEach(uri => {
          this.multiple_input_array_list.push({value : uri});
        })
      }

      this.details = Object.assign({}, this.origin);
      // console.log(JSON.stringify(this.details));
    },
......(이하생략)......

입력 양식 구현하기

입력양식입력 양식 목록, 신규 등록 입력 양식 및 각각의 버튼 이벤트를 초기화합니다.

<b-form-group
  label="Multiple Input to Array"
  label-for="input-multiple-input-array"
  label-cols="2"
>
  <template v-for="(uri, index) in multiple_input_array_list">
    <b-row
      :key="index"
      class="mb-1"
    >
      <b-col class="col-8">
        <b-form-input
          :name="'input-multiple-input-array-' + index"
          v-model="uri.value"
        >
        </b-form-input>
      </b-col>
      <b-col class="col-4">
        <b-button
          @click.stop.prevent="onDeleteMultipleArrayInput(uri.value)"
          variant="danger"
        >
          <i class="icon icon-trash"></i> 삭제
        </b-button>
      </b-col>
    </b-row>
  </template>
  <b-row>
    <b-col class="col-8">
      <b-form-input
        ref="input-multiple-input-array"
        id="input-multiple-input-array"
        name="input-multiple-input-array"
        v-model="multiple_input_array"
      >
      </b-form-input>
    </b-col>
    <b-col class="col-4">
      <b-button
        @click.stop.prevent="onAddMultipleArrayInput"
        variant="primary"
      >
        <i class="icon icon-plus"></i> 추가
      </b-button>
    </b-col>
  </b-row>
  <b-row>
    <b-col class="col-12">
      {{ multiple_input_array_list }}
    </b-col>
  </b-row>
  <!-- <b-row>
    <b-col class="col-12">
      {{ multipleInputToArray }}
    </b-col>
  </b-row> -->
</b-form-group>

      
<script>
export default {
  methods : {
    // 이벤트 처리
    onAddMultipleArrayInput() {
      const uri = this.multiple_input_array;
      // console.log("uri........ " + uri);
      if(uri !== "") {
        this.multiple_input_array_list.push({value : uri});
        this.multiple_input_array = "";
      }
    },
    onDeleteMultipleArrayInput(param) {
      let index = -1;
      this.multiple_input_array_list.some((uri, idx) => {
        if(uri.value === param) {
          index = idx;
          return true;
        }
      });
      if(index >= 0) {
        this.multiple_input_array_list.splice(index, 1);
      }
    },
  }
}
</script>

입력값 1차원값으로 변환하기

입력된 값을 1차원 문자열로 변환합니다. 변환된 데이터는 form데이터로 사용 가능합니다.

export default {
  name: 'Form',
  data () {
......(중간생략)......
  },
  computed: {
    multipleInputToArray() {
      let ret = "";
      let uris = [];
      if(Array.isArray(this.multiple_input_array_list) && this.multiple_input_array_list.length > 0) {
        this.multiple_input_array_list.forEach(uri => {
          uris.push(uri.value);
        });
        ret = uris.join(",");
      } else {
        ret = "";
      }

      return ret;
    },
......(이하생략)......

 

여러 개의 입력을 맵으로 처리하기

입력값 처리 변수 추가하기

export default {
  name: 'Form',
  data () {
    return {
      multiple_input_map_list: [],      // 배열처리된 입력양식의 값
      multiple_input_map_key: "",       // 값 추가를 위한 입력양식의 키
      multiple_input_map_value: "",     // 값 추가를 위한 입력양식의 값

      details : {},         // 입력양식의 현재 데이터
      origin : {},          // 입력양식의 기본 데이터(리셋 버튼클릭시 초기화될 값)
      defaults : {          // 기본값
        multiple_input_map_form: "{\"key1\":\"value1\", \"key2\":\"value2\", \"key3\":\"value3\"}",
      }
    }
  },

1차원 입력값을 배열로 변환하기

초기 데이터를 화면에 맞게 데이터를 변환 처리합니다. 초기 데이터는 관계형 데이터베이스에서 전달받는 데이터 형태(JSON과 같은 다중 깊이 MAP이 아닌 1차원 MAP)입니다.

export default {
  name: 'Form',
  data () {
......(중간생략)......
  },
  created() {
    this.setData(this.defaults);
  },
  methods : {
    setData(data) {
      this.origin = Object.assign({}, data);

      this.multiple_input_map_list = [];
      if(this.origin.multiple_input_map_form) {
        const obj = JSON.parse(this.origin.multiple_input_map_form);

        Object.keys(obj).forEach((key) => {
          this.multiple_input_map_list.push({key, value : obj[key]});
        })
      }

      this.details = Object.assign({}, this.origin);
      // console.log(JSON.stringify(this.details));
    },
......(이하생략)......

 

입력 양식 구현하기

입력양식입력 양식 목록, 신규 등록 입력 양식 및 각각의 버튼 이벤트를 초기화합니다.

<b-form-group
  label="Multiple Input to Map"
  label-for="input-multiple-input-map"
  label-cols="2"
>
  <template v-for="(value, index) in multiple_input_map_list">
    <b-row
      :key="index"
      class="mb-1"
    >
      <b-col class="col-4">
        <b-form-input
          :name="'input-multiple-input-map-key-' + index"
          v-model="value.key"
        >
        </b-form-input>
      </b-col>
      <b-col class="col-4">
        <b-form-input
          :name="'input-multiple-input-map-value-' + index"
          v-model="value.value"
        >
        </b-form-input>
      </b-col>
      <b-col class="col-4">
        <b-button
          @click.stop.prevent="onDeleteMultipleMapInput(value.key)"
          variant="danger"
        >
          <i class="icon icon-trash"></i> 삭제
        </b-button>
      </b-col>
    </b-row>
  </template>
  <b-row>
    <b-col class="col-4">
      <b-form-input
        id="input-multiple-input-map-key"
        name="input-multiple-input-map-key"
        v-model="multiple_input_map_key"
      >
      </b-form-input>
    </b-col>
    <b-col class="col-4">
      <b-form-input
        name="input-multiple-input-map-value"
        v-model="multiple_input_map_value"
      >
      </b-form-input>
    </b-col>
    <b-col class="col-4">
      <b-button
        @click.stop.prevent="onAddMultipleMapInput"
        variant="primary"
      >
        <i class="icon icon-plus"></i> 추가
      </b-button>
    </b-col>
  </b-row>
  <b-row>
    <b-col class="col-12">
      {{ multiple_input_map_list }}
    </b-col>
  </b-row>
  <!-- <b-row>
    <b-col class="col-12">
      {{ multipleInputToMap }}
    </b-col>
  </b-row> -->
</b-form-group>

      
<script>
export default {
  methods : {
    // 이벤트 처리
    onAddMultipleMapInput() {
      const key = this.multiple_input_map_key;
      const value = this.multiple_input_map_value;
      if(key !== "" && value !== "") {
        this.multiple_input_map_list.push({"key" : key, "value" : value});
        this.multiple_input_map_key = "";
        this.multiple_input_map_value = "";
      }
    },
    onDeleteMultipleMapInput(key) {
      let index = -1;
      this.multiple_input_map_list.some((info, idx) => {
        if(info.key === key) {
          index = idx;
          return true;
        }
      });
      if(index >= 0) {
        this.multiple_input_map_list.splice(index, 1);
      }
    },
  }
}
</script>

입력값 1차원값으로 변환하기

입력된 값을 1차원 문자열로 변환합니다. 변환된 데이터는 form데이터로 사용 가능합니다.

export default {
  name: 'Form',
  data () {
......(중간생략)......
  },
  computed: {
    multipleInputToMap() {
      let ret = "";
      const list = [];

      if(Array.isArray(this.multiple_input_map_list) && this.multiple_input_map_list.length > 0) {
        let multiple_input_map_list = {};
        this.multiple_input_map_list.forEach(info => {
          multiple_input_map_list[info.key] = info.value;
        });
        ret = JSON.stringify(multiple_input_map_list);
      } else {
        ret = "{}";
      }

      return ret;
    },
......(이하생략)......

 

 전체 소스

아래의 코드는 위 화면의 전체 소스입니다.

<template>
  <div>
    <b-form
      novalidate>
      
      <b-form-group
        label="Form Data (Default)"
        label-cols="2"
      >
        <pre style="color: white;">{{ defaults }}</pre>
      </b-form-group>

      <b-form-group
        label="Multiple Input to Array"
        label-for="input-multiple-input-array"
        label-cols="2"
      >
        <template v-for="(uri, index) in multiple_input_array_list">
          <b-row
            :key="index"
            class="mb-1"
          >
            <b-col class="col-8">
              <b-form-input
                :name="'input-multiple-input-array-' + index"
                v-model="uri.value"
              >
              </b-form-input>
            </b-col>
            <b-col class="col-4">
              <b-button
                @click.stop.prevent="onDeleteMultipleArrayInput(uri.value)"
                variant="danger"
              >
                <i class="icon icon-trash"></i> 삭제
              </b-button>
            </b-col>
          </b-row>
        </template>
        <b-row>
          <b-col class="col-8">
            <b-form-input
              ref="input-multiple-input-array"
              id="input-multiple-input-array"
              name="input-multiple-input-array"
              v-model="multiple_input_array"
            >
            </b-form-input>
          </b-col>
          <b-col class="col-4">
            <b-button
              @click.stop.prevent="onAddMultipleArrayInput"
              variant="primary"
            >
              <i class="icon icon-plus"></i> 추가
            </b-button>
          </b-col>
        </b-row>
        <b-row>
          <b-col class="col-12">
            {{ multiple_input_array_list }}
          </b-col>
        </b-row>
        <!-- <b-row>
          <b-col class="col-12">
            {{ multipleInputToArray }}
          </b-col>
        </b-row> -->
      </b-form-group>

      <b-form-group
        label="Multiple Input to Map"
        label-for="input-multiple-input-map"
        label-cols="2"
      >
        <template v-for="(value, index) in multiple_input_map_list">
          <b-row
            :key="index"
            class="mb-1"
          >
            <b-col class="col-4">
              <b-form-input
                :name="'input-multiple-input-map-key-' + index"
                v-model="value.key"
              >
              </b-form-input>
            </b-col>
            <b-col class="col-4">
              <b-form-input
                :name="'input-multiple-input-map-value-' + index"
                v-model="value.value"
              >
              </b-form-input>
            </b-col>
            <b-col class="col-4">
              <b-button
                @click.stop.prevent="onDeleteMultipleMapInput(value.key)"
                variant="danger"
              >
                <i class="icon icon-trash"></i> 삭제
              </b-button>
            </b-col>
          </b-row>
        </template>
        <b-row>
          <b-col class="col-4">
            <b-form-input
              id="input-multiple-input-map-key"
              name="input-multiple-input-map-key"
              v-model="multiple_input_map_key"
            >
            </b-form-input>
          </b-col>
          <b-col class="col-4">
            <b-form-input
              name="input-multiple-input-map-value"
              v-model="multiple_input_map_value"
            >
            </b-form-input>
          </b-col>
          <b-col class="col-4">
            <b-button
              @click.stop.prevent="onAddMultipleMapInput"
              variant="primary"
            >
              <i class="icon icon-plus"></i> 추가
            </b-button>
          </b-col>
        </b-row>
        <b-row>
          <b-col class="col-12">
            {{ multiple_input_map_list }}
          </b-col>
        </b-row>
        <!-- <b-row>
          <b-col class="col-12">
            {{ multipleInputToMap }}
          </b-col>
        </b-row> -->
      </b-form-group>
      
      <b-form-group
        label="Form Data"
        label-for="input-multiple-input-map"
        label-cols="2"
      >
        <pre style="color: white;">{{ multipleInputToForm }}</pre>
      </b-form-group>

      <div class="text-center">
        <b-button
          variant="primary"
          type="submit"
        >Submit</b-button>
        <b-button
          class="ml-1"
          type="reset"
          variant="danger"
        >Reset</b-button>
      </div>
    </b-form>
  </div>
</template>

<script>
export default {
  name: 'Form',
  data () {
    return {
      multiple_input_array_list : [],    // 배열처리된 입력양식의 값
      multiple_input_array: "",          // 값 추가를 위한 입력양식의 값

      multiple_input_map_list: [],      // 배열처리된 입력양식의 값
      multiple_input_map_key: "",       // 값 추가를 위한 입력양식의 키
      multiple_input_map_value: "",     // 값 추가를 위한 입력양식의 값

      details : {},         // 입력양식의 현재 데이터
      origin : {},          // 입력양식의 기본 데이터(리셋 버튼클릭시 초기화될 값)
      defaults : {          // 기본값
        multiple_input_array_form : "array1,array2,array3",
        multiple_input_map_form: "{\"key1\":\"value1\", \"key2\":\"value2\", \"key3\":\"value3\"}",
      }
    }
  },
  computed: {
    multipleInputToArray() {
      let ret = "";
      let uris = [];
      if(Array.isArray(this.multiple_input_array_list) && this.multiple_input_array_list.length > 0) {
        this.multiple_input_array_list.forEach(uri => {
          uris.push(uri.value);
        });
        ret = uris.join(",");
      } else {
        ret = "";
      }

      return ret;
    },
    multipleInputToMap() {
      let ret = "";
      const list = [];

      if(Array.isArray(this.multiple_input_map_list) && this.multiple_input_map_list.length > 0) {
        let multiple_input_map_list = {};
        this.multiple_input_map_list.forEach(info => {
          multiple_input_map_list[info.key] = info.value;
        });
        ret = JSON.stringify(multiple_input_map_list);
      } else {
        ret = "{}";
      }

      return ret;
    },
    multipleInputToForm() {

      const details = Object.assign({}, this.details);
      details.multiple_input_array_form = this.multipleInputToArray;
      details.multiple_input_map_form = this.multipleInputToMap;

      console.log(JSON.stringify(details));
      
      return JSON.stringify(details, null, 2);
    },
  },
  created() {
    this.setData(this.defaults);
  },
  methods : {
    setData(data) {
      this.origin = Object.assign({}, data);


      this.multiple_input_array_list = [];
      if(this.origin.multiple_input_array_form) {
        const arr = this.origin.multiple_input_array_form.split(",");
        arr.forEach(uri => {
          this.multiple_input_array_list.push({value : uri});
        })
      }


      this.multiple_input_map_list = [];
      if(this.origin.multiple_input_map_form) {
        const obj = JSON.parse(this.origin.multiple_input_map_form);

        Object.keys(obj).forEach((key) => {
          this.multiple_input_map_list.push({key, value : obj[key]});
        })
      }

      this.details = Object.assign({}, this.origin);
      // console.log(JSON.stringify(this.details));
    },
    onAddMultipleArrayInput() {
      const uri = this.multiple_input_array;
      if(uri !== "") {
        this.multiple_input_array_list.push({value : uri});
        this.multiple_input_array = "";
      }
    },
    onDeleteMultipleArrayInput(param) {
      let index = -1;
      this.multiple_input_array_list.some((uri, idx) => {
        if(uri.value === param) {
          index = idx;
          return true;
        }
      });
      if(index >= 0) {
        this.multiple_input_array_list.splice(index, 1);
      }
    },
    onAddMultipleMapInput() {
      const key = this.multiple_input_map_key;
      const value = this.multiple_input_map_value;
      if(key !== "" && value !== "") {
        this.multiple_input_map_list.push({"key" : key, "value" : value});
        this.multiple_input_map_key = "";
        this.multiple_input_map_value = "";
      }
    },
    onDeleteMultipleMapInput(key) {
      let index = -1;
      this.multiple_input_map_list.some((info, idx) => {
        if(info.key === key) {
          index = idx;
          return true;
        }
      });
      if(index >= 0) {
        this.multiple_input_map_list.splice(index, 1);
      }
    },
  }
}
</script>

 

참고자료

Vuejs: v-model array in multiple input

https://stackoverflow.com/questions/34825065/vuejs-v-model-array-in-multiple-input

 

 

 

728x90