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
'Tips, Tricks > Node, Vue, Electron' 카테고리의 다른 글
Ubuntu 에 LTS버전의 Node.js 설치하기(Installing LTS version of Node.js on Ubuntu) (0) | 2023.03.09 |
---|---|
Vue.js에서 동적 컴포넌트 사용하기(Dynamic Components in Vue.js) (0) | 2020.05.11 |
Vue.js에서 resize이벤트 처리하기 (0) | 2020.05.07 |
break 처리를 위한 forEach 대신 some으로 변경하기 (0) | 2020.03.17 |
Vue.js Filter : 3자리마다 쉼표찍기와 bytes 길이 자동 표시(Pretty currency & Pretty size of bytes) (0) | 2020.03.10 |