Nuxt 프로젝트 진행을 하며 Accordion 메뉴를 구현 중 문제가 발생하였다.
평소에는 v-for로 작업하여 Accordion 메뉴 구현에 있어서 data를 받아와 true, false 처리를 하는데 전혀 문제가 없엇는데 현재 구조는 메뉴가 변할일이 없는 구조라 v-for를 사용하지 않고 전부 마크업으로 처리하게되었다, 그래서 methods에 key값을 파라미터로 받아와서 이벤트를 달아줘야하는데 이걸 구현을 못해서 여기서 와 이걸 못한다고? 생각에 자괴감도 들었음ㅎㅎ; 그리고 Data로 접근해야하는걸 DOM조작을 해서 하려함 굳이,,?
//markup
<div class="depth-nav" :class="{ 'is-active': depthNavState.data1 }">
<button type="button" class="h3" @click="onTabToggle('')">
<span>1Depth</span>
<i class="ic-expand-more" />
</button>
<div v-if="" class="depth-menu">
<nuxt-link to="">
<span class="bt-1r">2Depth</span>
</nuxt-link>
<nuxt-link to="">
<span class="bt-1r">2Depth</span>
</nuxt-link>
<nuxt-link to="">
<span class="bt-1r">2Depth</span>
</nuxt-link>
<nuxt-link to="">
<span class="bt-1r">2Depth</span>
</nuxt-link>
<nuxt-link to="">
<span class="bt-1r">2Depth</span>
</nuxt-link>
<nuxt-link to="">
<span class="bt-1r">2Depth</span>
</nuxt-link>
</div>
</div>
data() {
return {
depthNavState: {
data1: false,
data2: false,
data3: false,
data4: false,
data5: false
}
};
},
methods: {
onTabToggle() {
}
}
구조는 이런식으로 작성되었고 button을 클릭했을때 depthNavState의 true, false 조작을 key값으로 구분하여 작동시켜려 하였다, 하지만ㅋㅋ
//markup
<div class="depth-nav" :class="{ 'is-active': depthNavState.data1 }">
<button type="button" class="h3" @click="onTabToggle(depthNavState)">
<span>1Depth</span>
<i class="ic-expand-more" />
</button>
<div v-if="" class="depth-menu">
<nuxt-link to="">
<span class="bt-1r">2Depth</span>
</nuxt-link>
<nuxt-link to="">
<span class="bt-1r">2Depth</span>
</nuxt-link>
<nuxt-link to="">
<span class="bt-1r">2Depth</span>
</nuxt-link>
<nuxt-link to="">
<span class="bt-1r">2Depth</span>
</nuxt-link>
<nuxt-link to="">
<span class="bt-1r">2Depth</span>
</nuxt-link>
<nuxt-link to="">
<span class="bt-1r">2Depth</span>
</nuxt-link>
</div>
</div>
data() {
return {
depthNavState: {
data1: false,
data2: false,
data3: false,
data4: false,
data5: false
}
};
},
methods: {
onTabToggle(depthNavState) {
// const key = Object.entries(depthNavState);
// key.map((item, index) => {
// return console.log({ ...item, index });
// });
// for (const key in depthNavState) {
// console.log(`${key} ${depthNavState[key]}`);
// }
console.log(Reflect.has(depthNavState));
}
}
눈물의 똥꼬쇼가 시작되었다;; key 값을 찾겠다고 Object.entries 부터 순환 할 필요가 없는데 map으로 순환을 하고 있고 여기서 뽑은 key값을 저걸 어떻게 data 접근해서 비교해야하냐 하면서 머리 끙끙 앓다가
<button type="button" class="h3" @click="onTabToggle(this.depthNavState.data1 = !this.depthNavState.data1)">
이 충동까지 와버렸다가 마음을 가다듬고 코드를 작성하기 시작하는데 시간이 지나도 마음은 가다듬어지지않고 내 뇌는 쪼그라들고 쓰러지기 직전에 프론트 개발자분께 도움을 얻었다. 그저 빛,,
프론트 개발자님 : '왜 이렇게 어렵게 생각하세요? 그냥 클릭 이벤트에 파라미터로 key값을 스트링으로 보내주면 되자나용'
🐖 : '????'
<button type="button" class="h3" @click="onTabToggle('data1')">
methods: {
onTabToggle(target) {
this.depthNavState[`${target}`] = !this.depthNavState[`${target}`];
}
}
시간을 거슬러,, 공부했던 파일들을 찾아보았다, 완전 기본적인걸 잊고있었고 아 역시 직접해봐야 아는구나 싶었다ㅎㅎ
let apple = {
name: "apple",
"hello-bye": "✌",
};
//속성, 데이터에 접근하기
apple.name; // 마침표 표기법 dot notation
console.log(apple["hello-bye"]); //대괄호 표기법 bracket notation
apple["name"];
심지어 겁나 잘 적어놓음;;ㅋㅋㅋ 이렇게 접근하는 방법을 아에 잊어버리고 있었고 사용을 하지않으니 자연스럽게 잊혀진거였는데 지금 보니 코드 1줄이면 끝날걸 그렇게 고민하다니,,
해결 후 저렇게만 작성해 놓으면 모든 메뉴들이 펼쳐져 한개가 펼쳐지면 한개는 닫히게 처리해주었다. key값이 target과 일치하지 않는것들은 false로 처리하게 해주었다. 눈물의 똥꼬쇼할때 사용하던 Object.keys 드디어 사용함🤣
onTabToggle(target) {
Object.keys(this.depthNavState).forEach((key) => {
if (target !== key) {
this.depthNavState[`${key}`] = false;
}
});
this.depthNavState[`${target}`] = !this.depthNavState[`${target}`];
}
split() 으로 구분자 쉼표('/')를 기준으로 문자열을 잘라서 this.depthNavState key값 과 비교하여 같으면 data true 처리해주기도 진행하였다. 이제 Redirect해도 route path를 가져와서 route에 따라 active 효과가 적용된다.
created() {
const firstDepthRoute = this.$route.path.split('/')[2] || null;
Object.keys(this.depthNavState).forEach((key) => {
if (firstDepthRoute === key) {
this.depthNavState[`${key}`] = true;
}
});
},
computed name() 함수에 nameValue를 가져와 length 체크해서 말줄임 표시해주기
<h4>안녕하세요, <span>{{ name }}</span>님!</h4>
data() {
return {
nameValue: '이름테스트',
};
},
computed: {
name() {
return this.nameValue.length > 4 ? `${this.nameValue.slice(0, 4)}...` : this.nameValue;
}
},