1. 설명
1) 화면을 불러올때 행 데이터 배열을 Spring Back-End에서 조회한 뒤 화면에 뿌려주는 흐름입니다.
2) 추후 기존 originData는 DB에서 가져온 데이터로 표시하여 행이 삭제될때 DB도 함께 삭제되도록 구현하기위해 연관 코드가 존재합니다.
2. <template> </template> code
1) colList 내부의 row object 마다 v-model:value로 양방향 바인드하여 입력 받는 값이 바인딩 되도록 구현하였습니다.
2) fn_rowReadonly 함수는 아래 코드가 없어 기술합니다. 해당 object에 readOnly 속성에 따라 변경됩니다.
<tr v-for="(row, index) in colList" :key="`${row}` + index">
<td class="text-center"> {{ index }}
<CheckBox :id="index" :value="row.colIndex" v-model="checkedIndex" :key="index" />
</td>
<td class="text-start">
<InputText v-model:value="row.COLUMN_NM" :readonly="fn_rowReadonly(row)" />
</td>
<td class="text-start">
<InputText v-model:value="row.DATA_TYPE" :readonly="fn_rowReadonly(row)" />
</td>
<td class="text-end">
<InputText v-model:value="row.DATA_SIZE" :readonly="fn_rowReadonly(row)" />
</td>
<td class="text-start">
<InputText v-model:value="row.CMMNT" :readonly="fn_rowReadonly(row)" />
</td>
<td>
<InputText v-model:value="row.RMK" />
</td>
</tr>
3. 버튼 이벤트 code
<div class="row">
<div class="btn_area float-end">
<button type="button" class="btn secondary" @click="fn_addRow">
<span class="txt">+ 행추가</span>
</button>
<button type="button" class="btn secondary" @click="fn_removeRow(0)">
<span class="txt">- 행삭제</span>
</button>
</div>
</div>
4. data(){} code
ajax 통신을 이용한 데이터를 받아 저장할 배열 선언, 체크한 행 index를 담아둘 변수 선언
1) reactive() 로 배열을 정의해둔 이유는 배열에 요소를 추가하거나 제거할 때, Vue가 자동으로 변경사항을 감지하고 관련된 컴포넌트를 업데이트시키도록 하기 위함입니다.
data(){
…
colList: reactive([]),
checkedIndex: [],
…
}
5. methods: code
1) 선택한 배열의 인덱스를 역순으로 삭제하는 이유
- [0] , [1] , [2], [3] 의 배열이 있다고 가정할 때
- 0, 2 인덱스 값 삭제 진행
- 0을 삭제 하였을 경우 배열이 [1], [2], [3] 으로 변하게 되고 이때 인덱스 2의 값은 [2] -> [3] 으로 됩니다.
- 뒤에서 부터 삭제하면 이와 같은 상황을 방지 할 수 있습니다.
methods: {
async fn_removeRow() {
this.crudMode = 'D';
let indicesToRemove = await this.selIndicesToArr();
//기존 사용 컬럼 목록 확인
this.removeColList = await this.fn_originChk(indicesToRemove);
if (0 < this.removeColList.length) {
//DB Data 삭제 진행
} else {
//Front-End 삭제 진행
indicesToRemove.forEach(index => {
this.colList.splice(index, 1);
});
this.checkedIndex = []; // 선택된 행 초기화
}
},
async selIndicesToArr() {
let indicesToRemove = this.checkedIndex.map(checkedItem =>
this.colList.findIndex(item => item.colIndex === checkedItem)
);
indicesToRemove.sort((a, b) => b - a); // 역순으로 정렬하여 뒤에서부터 삭제
return indicesToRemove;
},
fn_rowReadonly(row) {
return row.readonly !== null && row.readonly !== false
},
fn_addRow() {
var colIndex = this.colList.length;
this.colList.push({ "colIndex": colIndex, "readonly": false, "isOriginalData": false });
},
//컬럼 리스트 조회
async fn_getColList(data) {
const params = {
tableNm: data
};
await axios.post(process.env.VUE_APP_API_URL+'/getData.do', params)
.then(response => {
var i = 0;
this.colList = response.data.map(item => {
var ret = { ...item, isOriginalData: true, colIndex: i };
i++;
return ret;
});
})
.catch(error => {
console.log('error >> ' + error)
})
},
async fn_originChk(rmveChkArry) {
var ret = [];
rmveChkArry.forEach(index => {
var item = this.colList[index];
var orginChk = true;
if (item.isOriginalData == null || typeof item.isOriginalData == "undefined") {
orginChk = false;
}
if (item.isOriginalData && orginChk) {
var col = this.colList[index];
ret.push(col)
}
});
return ret;
},
}
6. computed: code
전체 선택, 전체 선택 해제 관련 코드
computed: {
...
allSelected: {
//getter
get: function () {
// 모든 `colList` 항목의 ID가 `checkedIndex`에 포함되어 있는지 확인
return this.colList.every(row => this.checkedIndex.includes(row.colIndex));
},
set: function (value) {
// `value`가 참이면 모든 항목의 ID를 `checkedIndex`에 할당, 거짓이면 빈 배열 할당
this.checkedIndex = value ? this.colList.map(row => row.colIndex) : [];
}
},
},
v-model:value와 v-model의 차이
v-model:value는 주로 Vue 3에서 컴포넌트에 사용될 때 명시적으로 prop 이름을 지정할 필요가 있을 때 사용됩니다. 예를 들어, 사용자 정의 컴포넌트에서 value prop을 다루는 경우 v-model 대신 v-model:value를 사용하여 명확하게 할 수 있습니다. 그러나 일반적인 HTML 폼 요소에서는 v-model만 사용해도 충분합니다. Vue 3에서는 v-model을 사용하여 다른 prop 이름에 대한 양방향 바인딩도 구현할 수 있으며, 이를 위해 v-model:propName 형식을 사용합니다. 따라서 예제의 v-model:value는 정해진 문법이 아니라 value라는 propName입니다! ㅎ
'Front-End > Vue.js' 카테고리의 다른 글
| Chat GPT에게 물어본 watch의 deep옵션 (0) | 2024.02.22 |
|---|---|
| axios response undefind 문제 (0) | 2024.02.22 |
| Vue Warn 사례 (0) | 2024.02.22 |