Search Form
조건 기반 검색 기능을 제공하는 공통 폼 컴포넌트입니다.
이 컴포넌트는 내부적으로
<el-form>
을 사용하고 있으며, 해당 컴포넌트의 속성들을 그대로 상속받아 활용할 수 있습니다. 자세한 속성 목록은 공식문서를 참고하세요.
props
이름 | 타입 | 기본값 | 설명 |
---|---|---|---|
use-advanced | Boolean | false | 고급 검색 UI를 사용할지 여부 |
use-accordion | Boolean | false | 아코디언 UI를 사용할지 여부 |
always-expanded | Boolean | false | 고급 검색이 항상 펼쳐져 있을지 여부 |
use-tab | Boolean | false | 탭 UI 사용 여부 (고급 검색 내에 탭 구조) |
tab-position | number | 'top' | 탭 위치 top , left , right , bottom |
tab-items | Array<{ name: string; label: string }> | [] | 탭 구성 항목 (탭 이름, 라벨) |
nv-filter | Object | {} | 필터 관련 객체, 내부 로직에서 사용 (filter.value , query.value 등과 연결) |
content-style | Object | {width: '800px'} | 모달 컨텐츠 스타일 설정 |
column-size | number | 2 | 고급 검색 grid 컬럼 개수 기준 값 |
inline-tag | boolean | true | 인라인 검색 태그를 보여줄지 여부 |
filter-tag | boolean | true | 고급 검색 모달 안에서도 검색 태그 보여줄지 여부 |
inline-reset | boolean | true | 인라인 영역에서 초기화 버튼 보여줄지 여부 |
filter-reset | boolean | true | 고급 검색 영역에서 초기화 버튼 보여줄지 여부 |
tag-type | string | 'primary' | 검색 태그 <el-tag> 의 type 속성 (success , warning , info 등 사용 가능) |
tag-effect | string | 'light' | 검색 태그 <el-tag> 의 effect 속성 (dark , light , plain ) |
tag-color | string / undefined | undefined | 검색 태그 <el-tag> 의 color (Hex나 CSS 색상 값) |
label-position | string | 'top' | Form label 위치 (top , left , right ) |
label-width | string | 'auto' | 라벨 너비 설정 ('auto' , '80px' 등) |
Slot
이름 | 설명 |
---|---|
inline | 기본 인라인 검색 영역 |
filters | 고급 검색 필터 (탭 없음) |
item.name | 고급 검색 탭별 필터 (슬롯 동적 이름) |
footer | 고급 검색 모달 하단 |
Event
이름 | 발생 시점 | 설명 |
---|---|---|
@submit | 검색 버튼, 필터 변경 후 태그 삭제 시 | 검색 조건을 반영하여 검색 수행 |
@reset | 초기화 버튼 클릭 시 | 모든 검색 조건 초기화 |
@cancel | 고급 검색 취소 버튼 클릭 시 | 검색 조건 변경을 취소하고 창을 닫음 |
기본 검색
<template #inline>
슬롯을 사용하여 기본적인 인라인 검색 필드를 배치합니다.nv-search-dynamic
컴포넌트를 통해 키워드 검색 필드를 구현하고,nv-lv-mapper
를 사용하여 검색 대상 필드 목록을 연결합니다.@submit
이벤트 핸들러 (onSearch
)는 검색 버튼 클릭 시 검색 로직을 수행하도록 연결됩니다.@reset
이벤트 핸들러 (resetQuery
및retrieve
)는 초기화 버튼 클릭 시 검색 조건을 초기화하고 검색 결과를 다시 불러오도록 연결됩니다.
HTML
<nv-search-form
@submit="onSearch"
@reset="resetQuery() || retrieve()"
@cancel="(arg) => query.q = _d.merge({}, arg)"
:nv-filter="nvFilter">
<template #inline>
<nv-search-dynamic :nv-filter="nvFilter" nv-key="keyword" :nv-lv-mapper="codes.keyword" />
</template>
</nv-search-form>
typescript
import {markRaw, nextTick, onMounted, ref} from 'vue';
import useQuery from 'components/composables/useQuery';
import {filterTool} from 'src/components/plugins/search';
const dataPerPageList = [40, 60, 100, 200];
const pagination = ref();
const {query} = useQuery();
const nvFilter = ref();
const loaded = ref(false);
onMounted(async () => {
await init();
});
const init = async () => {
query.dataPerPage = dataPerPageList[0];
nvFilter.value = new filterTool.NvFilter(query);
nvFilter.value.build();
loaded.value = true;
await nextTick();
retrieve();
}
// ------------------------------------------------------------------------- event handler
const resetQuery = () => {
query.q = nvFilter.value.resetQ();
}
const retrieve = () => {
pagination.value.go(1, query);
}
const onSearch = () => {
retrieve();
}
const paginated = (data) => {
list.value = data;
}
고급검색 추가 (use-advanced)
use-advanced
prop을true
로 설정하면 고급 검색 버튼이 활성화됩니다.<template #filters>
슬롯 내부에 다양한nv-search-*
컴포넌트들을 배치하여 고급 검색 폼을 구성합니다. 텍스트 입력, 셀렉트 박스, 코드(드롭다운), 기간 선택, 토글 스위치, 체크박스 등 다양한 검색 조건을 추가할 수 있습니다.
HTML
<nv-search-form
@submit="onSearch"
@reset="resetQuery() || retrieve()"
@cancel="(arg) => query.q = _d.merge({}, arg)"
use-advanced
:nv-filter="nvFilter">
<template #inline>
기본 검색폼
</template>
<template #filters>
고급 검색폼
</template>
</nv-search-form>
아코디언 형태 변환 (use-accordion)
use-accordion
prop을true
로 설정하면 고급 검색 영역이 초기에는 접혀진 아코디언 형태로 표시되고, 버튼 클릭 시 펼쳐져 고급 검색 조건을 확인할 수 있습니다.- 이는 화면 공간을 효율적으로 활용하고자 할 때 유용합니다.
HTML
<nv-search-form :nv-filter="nvFilter"
use-accordion>
<template #inline>
기본 검색폼
</template>
<template #filters>
고급 검색폼
</template>
</nv-search-form>
고급 검색 상시 노출 (always-expanded)
always-expanded
prop을true
로 설정하면 고급 검색 영역(#filters
슬롯의 내용)이 초기부터 펼쳐진 상태로 사용자에게 노출됩니다.- 사용자가 고급 검색 조건을 자주 사용하거나, 주요 검색 옵션을 항상 보여주고 싶을 때 유용합니다.
HTML
<nv-search-form :nv-filter="nvFilter"
always-expanded>
<template #filters>
고급 검색폼
</template>
</nv-search-form>
Tab 추가
use-tab
prop을true
로 설정하고tab-items
prop을 통해 탭 목록을 정의하면, 고급 검색 영역 내에 탭 인터페이스가 생성됩니다.<template v-slot:name>
형태로 각 탭에 해당하는 검색 필드들을 배치할 수 있으며,tab-items
의name
속성과 슬롯 이름이 정확히 일치해야 합니다.- 이는 고급 검색 조건이 많아 여러 그룹으로 나누어 표시하고 싶을 때 유용합니다.
HTML
<nv-search-form :nv-filter="nvFilter"
always-expanded
use-tab
:tab-items="tabItem">
<template #inline>
기본 검색폼
</template>
<template #test>
테스트 슬롯
</template>
<template #test2>
테스트2 슬롯
</template>
<template #test3>
테스트3 슬롯
</template>
<template #test4>
테스트4 슬롯
</template>
</nv-search-form>
typescript
const tabItem = [
{name : 'test', label : '테스트'},
{name : 'test2', label : '테스트2'},
{name : 'test3', label : '테스트3'},
{name : 'test4', label : '테스트4'},
]
WARNING
각 tabItem.name
은 <template v-slot:[name]>
과 정확히 일치해야 합니다.
tab-position
tab-position
prop을 사용하여 고급 검색 탭의 위치를top
,left
,right
,bottom
중 하나로 변경할 수 있습니다.
HTML
<el-radio-group v-model="tabPosition" class="q-mb-md">
<el-radio value="top">top</el-radio>
<el-radio value="left">left</el-radio>
<el-radio value="right">right</el-radio>
<el-radio value="bottom">bottom</el-radio>
</el-radio-group>
<nv-search-form :nv-filter="nvFilter"
always-expanded
use-tab
:tab-items="tabItem"
:tab-position="tabPosition">
<template #inline>
기본 검색폼
</template>
<template #test>
테스트 슬롯
</template>
</nv-search-form>
typescript
const tabPosition = ref('top')
column-size
column-size
prop은 고급 검색 영역(#filters
슬롯) 내부에 배치되는 검색 필드들의 최대 컬럼 개수를 지정합니다.- 이는 그리드 레이아웃을 기반으로 하며, 한 줄에 표시될 수 있는 필드의 수를 조절하여 고급 검색 폼의 레이아웃을 구성하는 데 사용됩니다.
HTML
<el-input-number v-model="columnSize" :min="1" :max="5" class="q-mb-md" />
<nv-search-form
use-advanced
:nv-filter="nvFilter"
:column-size="columnSize">
<template #inline>
기본 검색폼
</template>
<template #filters>
고급 검색폼
</template>
</nv-search-form>
typescript
const columnSize = ref(2)
Label
label-position
label-position
prop을 사용하여 폼 전체의 라벨 위치를top
,left
,right
중 하나로 설정할 수 있습니다.
HTML
<el-radio-group v-model="labelPosition" class="q-mb-md">
<el-radio value="top">top</el-radio>
<el-radio value="left">left</el-radio>
<el-radio value="right">right</el-radio>
</el-radio-group>
<nv-search-form
use-advanced
:nv-filter="nvFilter"
:label-position="labelPosition">
<template #inline>
기본 검색폼
</template>
<template #filters>
고급 검색폼
</template>
</nv-search-form>
typescript
const labelPosition = ref('top')
label-width
label-width
prop을 사용하여 폼 라벨의 너비를 명시적으로 지정합니다.'auto'
로 설정하면 라벨 내용에 따라 자동으로 너비가 조정되고,'80px'
과 같은 CSS width 값을 지정하여 고정 너비를 사용할 수도 있습니다.label-position
이left
또는right
일 때,'auto'
는 가장 긴 라벨을 기준으로 너비를 설정합니다.
label-position :
label-width :
label-width :
HTML
<div>
<small>label-position : </small>
<el-radio-group v-model="labelPosition2" class="q-ml-md">
<el-radio value="top">top</el-radio>
<el-radio value="left">left</el-radio>
<el-radio value="right">right</el-radio>
</el-radio-group>
<br/>
<small>label-width : </small>
<el-radio-group v-model="labelWidth" class="q-mb-md q-ml-md">
<el-radio value="auto">auto</el-radio>
<el-radio value="100px">100px</el-radio>
</el-radio-group>
</div>
<nv-search-form
use-advanced
:nv-filter="nvFilter"
:label-position="labelPosition2"
:label-width="labelWidth">
<template #inline>
기본 검색폼
</template>
<template #filters>
고급 검색폼
</template>
</nv-search-form>
typescript
const labelPosition2 = ref('right')
const labelWidth = ref('auto')