웹사이트를 사용하면서 정말 편리한 기능을 발견해서 저도 똑같은 기능을 구현해보았습니다.
그것은 바로 버튼 없이, 엔터 없이, 실시간으로 검색하는 것 입니다.
시작 전에 필요한 것은 Vue와 JS를 간단히 알기^^, JSON 데이터 입니다.
JSON 데이터를 가져오는 방법은 아래 링크를 참고해주세요!
⬇⬇⬇
⬆⬆⬆
assets/group.json
[
{
"name": "아이브",
"debut": "2021",
"member": "6"
},
{
"name": "스테이씨",
"debut": "2020",
"member": "6"
},
{
"name": "뉴진스",
"debut": "2022",
"member": "5"
},
{
"name": "에스파",
"debut": "2020",
"member": "4"
},
{
"name": "엔믹스",
"debut": "2022",
"member": "7"
},
{
"name": "르세라핌",
"debut": "2022",
"member": "5"
}
]
app.vue
<template>
<div>
<input
class="search-input"
type="text"
placeholder="그룹명, 데뷔년도, 멤버수를 입력하세요"
/>
<ul class="group-list">
<li class="group-list-header">
<span>그룹명</span>
<span>데뷔년도</span>
<span>멤버수</span>
</li>
<li v-for="group in groupList" :key="group" class="group-item">
<span>{{ group.name }}</span>
<span>{{ group.debut }}</span>
<span>{{ group.member }}</span>
</li>
</ul>
</div>
</template>
<script>
import data from "@/assets/group.json";
const groupList = data;
export default {
data() {
return {
groupList,
};
}
}
</script>
<style>
* {
padding: 0;
margin: 0;
}
.search-input {
display: block;
padding: 4px 8px;
margin: 10px auto;
width: 320px;
font-size: 16px;
outline: none;
}
.group-list {
margin: 0 auto;
width: 360px;
}
.group-list li {
display: flex;
justify-content: center;
align-items: center;
height: 32px;
list-style-type: none;
}
.group-list span {
display: block;
width: 33%;
text-align: center;
}
.group-list-header {
font-weight: 700;
border-bottom: 1px solid #bdbdbd;
}
</style>
검색창에 입력을 해도 아무런 동작이 되지 않는 정적이 화면이 완성되었습니다.
우리가 만들 기능은 실시간으로 검색어를 입력 받고 동일한 문자열을 지닌 데이터만 보여주는 것 입니다.
<template>
<div>
<input
class="search-input"
type="text"
placeholder="그룹명, 데뷔년도, 멤버수를 입력하세요"
@input="searchGroup($event)"
/>
<!-- 위와 동일 -->
</div>
</template>
<script>
import data from "@/assets/group.json";
const groupList = data;
export default {
data() {
return {
groupList,
};
},
methods: {
searchGroup(event) {
// console.log(event.target.value);
const len = this.groupList.length;
for (let i = 0; i < len; i++) {
if (
this.groupList[i].name.includes(event.target.value) === false &&
this.groupList[i].debut.includes(event.target.value) === false &&
this.groupList[i].member.includes(event.target.value) === false
) {
document.querySelectorAll(".group-item")[i].style.display = "none";
} else {
document.querySelectorAll(".group-item")[i].style.display = "flex";
}
}
},
},
};
</script>
<style>
/* 위와 동일 */
</style>
함수 하나만 추가하면 완성이 됩니다.
input
안에 @input="searchGroup($event)"
를 넣습니다. $event
란 ... 제가 한마디로 설명하기에 100프로 이해는 못했지만 키보드 입력을 받을 때 사용합니다! (더 자세히 공부를 해야겠어요...)
searchGroup
함수에는 name
, debut
, member
어디에도 입력 받은 값이 존재하지 않으면 해당 .group-item
을 숨기는 기능을 넣어야 합니다.
모든 .group-item
에 적용하기 위해서 반복문을 사용하였습니다. 이때 반복 횟수만큼 매번 array.length
속성을 참조하는 것이 비효율적이기 때문에
const len = this.groupList.length;
으로 다시 선언하였습니다.
조건문을 사용해서 '세가지 값 어디에도 입력 값이 존재하지 않다면'과 '그렇지 않으면(셋 중 하나라도 존재하면)'으로 나누어 생각하였습니다.
문자열 포함 여부를 알기 위해서 includes()
함수를 사용하였습니다. 입력값은 event.target.value
로 알 수 있습니다.
console.log(event.target.value);
위 콘솔 명령을 입력하시면 키보드가 눌린 대로 콘솔에 작성된 것을 확인할 수 있습니다.
<template>
<div>
<input
class="search-input"
type="text"
placeholder="그룹명, 데뷔년도, 멤버수를 입력하세요"
@input="searchGroup($event)"
/>
<ul class="group-list">
<li class="group-list-header">
<span>그룹명</span>
<span>데뷔년도</span>
<span>멤버수</span>
</li>
<li v-for="group in groupList" :key="group" class="group-item">
<span>{{ group.name }}</span>
<span>{{ group.debut }}</span>
<span>{{ group.member }}</span>
</li>
</ul>
</div>
</template>
<script>
import data from "@/assets/group.json";
const groupList = data;
export default {
data() {
return {
groupList,
};
},
methods: {
searchGroup(event) {
const len = this.groupList.length;
for (let i = 0; i < len; i++) {
if (
this.groupList[i].name.includes(event.target.value) === false &&
this.groupList[i].debut.includes(event.target.value) === false &&
this.groupList[i].member.includes(event.target.value) === false
) {
document.querySelectorAll(".group-item")[i].style.display = "none";
} else {
document.querySelectorAll(".group-item")[i].style.display = "flex";
}
}
},
},
};
</script>
<style>
* {
padding: 0;
margin: 0;
}
.search-input {
display: block;
padding: 4px 8px;
margin: 10px auto;
width: 320px;
font-size: 16px;
outline: none;
}
.group-list {
margin: 0 auto;
width: 360px;
}
.group-list li {
display: flex;
justify-content: center;
align-items: center;
height: 32px;
list-style-type: none;
}
.group-list span {
display: block;
width: 33%;
text-align: center;
}
.group-list-header {
font-weight: 700;
border-bottom: 1px solid #bdbdbd;
}
</style>
ex 1 | ex 2 | ex 3 |
---|---|---|