- 전체
- 명
- 오늘 찾아주신 분
- 명
UI 를 만들다 보면, 디자이너가 그려주는 UI 에서는 시스템에서 제공해주는 UI 와는 많이 다른 신기하게 생긴 컴포넌트들이 많이 보이곤 한다.
게다가 기능이 이미 코어에도 존재하는 것들, <input> 계열의 checkbox 나 radio, <select> 의 경우에는 기능은 유지하되, 겉의 모습만 바뀌는 것을 많이 볼 수 있다. 하지만 <div> 레이어 같은 아이들이 아니라서 새로 스타일을 정의하기에는 많은 어려움을 가지고 있다.
그래서 이런 것들은 웬만하면 크게 커스터마이즈하여 디자인을 맞추곤 하는데, 이번 포스팅은 그 중에서 커스터마이즈 하기가 쉬운 Checkbox 를 Vue.js 를 통해서 만져보도록 하겠다.
먼저 일반적인 체크박스 의 구조를 보게 되면,
1. 라벨이 씌워지지 않은 체크박스
2가지 타입의 체크박스를 볼 수 있다. 해당 타입들을 소스로 본다면,
<input type="checkbox"> 1. 라벨이 씌워지지 않은 체크박스
<label for="chk"><input id="chk" type="checkbox">2. 라벨이 씌워진 체크박스</label>
둘의 차이는, 전자는 체크박스 영역만 눌러야 ON/OFF 가 변경되고 후자는 체크박스 영역 뿐만 아니라 글씨 영역도 클릭하면 체크 ON/OFF 에 반영이 되는 것이다. 보통 후자의 방식으로 사용되곤 한다.
그래서, 후자의 방식으로 시작을 해보도록 하자.
1. Vue 컴포넌트 생성
먼저, 독립적인 vue 파일을 생성했고, 기본적인 골격을 삽입해준다.
<templete>
<label for="chk">
<input id="chk" type="checkbox">
</label>
</templete>
<script>
export default {
name: 'Checkbox',
}
</script>
여기에서 prop 으로 체크박스의 값을 입력받을 변수와, 라벨에 들어갈 문자가 들어갈 변수를 추가해준다.
<templete>
<label for="chk">
<input id="chk" type="checkbox" :value="checked">
{{ label }}
</label>
</templete>
<script>
export default {
name: 'Checkbox',
props: {
checked: {
type: Boolean,
default: false
},
label: String,
},
}
</script>
그럼 외부에서는 다음의 형태로 접근할 수 있을 것이다.
<checkbox label="체크박스입니다" checked="true" />
이 상태에서 컴포넌트를 등록하고 사용하려 해도 데이터를 받지 못한다. 그래서 양방향 데이터 바인딩 이라는 방식을 적용해 주어야 하는데 적용을 하게되면 컴포넌트 외부에서 체크박스 컴포넌트의 상태 변경을 알 수 있다.
자세한 사항은 공식 홈페이지 문서를 참조하도록 한다
지금의 소스에서양방향 데이터 바인딩을 적용해본다면,
1. 외부에서 컴포넌트로 접근할 수 있는 변수를 'checked' 로 지정해 준다.
2. <input> 에 체크박스가 눌린 이벤트가 감지되면, 상태값 변경에 대해 알려준다
<templete>
<label for="chk">
<input id="chk" type="checkbox" :value="checked" @input="$emit('input', !checked)">
{{ label }}
</label>
</templete>
<script>
export default {
name: 'Checkbox',
props: {
checked: {
type: Boolean,
default: false
},
label: String,
},
model: {
prop: 'checked',
event: 'input'
}
}
</script>
1 항목의 경우는, 컴포넌트 옵션에 model 을 통해서 가능하다. model 옵션을 사용해야 외부에서 v-model 을 통해서 컴포넌트에 접근할 수 있다.
<checkbox v-model="checked" label="체크박스" />
prop 속성은 변수명을 넣어서 지정하면 되며, event 는 어떤 이벤트가 $emit 을 통해 불려지면 지정한 prop 의 값을 변경할 지 입력 하는 곳이다.
예를 들어, model 의 prop 가 'selected' 이고 event 가 'changed' 라고 하면, $emit('changed', 0); 을 호출할 경우 selected 는 0 이 들어갈 것이고 컴포넌트 외부에도 0으로 알려줄 것이다. 1 이면 1을 알려줄 것이다.
여기까지 일단 체크박스에 대한 컴포넌트를 만들어주었다. 다음은 스타일을 입혀보자
2. Style 적용
일단, 스타일에 대해서는 사용자가 짜기 나름이기 때문에 예시가 100% 정답이 아닐 수 있는 것을 감안하자.
먼저, 기존 체크박스를 대체할 UI 를 만들기 위해서 ON/OFF 이미지를 준비한다.
그리고서 <template> 에 새 체크박스이미지가 들어갈 부분을 추가해준다.
<templete>
<label for="chk">
<input id="chk" type="checkbox" :value="checked" @input="$emit('input', !checked)">
<span class="check" :class="{ on : checked }"></span>
{{ label }}
</label>
</templete>
checked 값이 변경 될 때마다 on 클래스가 check 뒤에 붙고 빠지고 하면서 ON/OFF 상태 값을 변경할 것이다.
다음은 <style> 태그를 사용하여 UI 를 세세하게 변경을 시켜주도록 한다. 변경 하면서 다음의 명세를 코드도 함께 포함할 것이다.
1. 기존의 체크박스 UI는 사용하지 않기 때문에 보이지 않도록 한다.
2. 체크박스 ON/OFF 에 따라 이미지를 뿌려주도록 한다.
<style>
label { display:inline-block; cursor: pointer; }
/* 1번 명세 */
input[type="checkbox"] { display: none; }
/* 2번 명세 */
span.check { display:inline-block; width: 24px; height: 24px; background: url('${check_off_image}') no-repeat; background-size: 100%; }
span.check.on { background: url('${check_on_image}') no-repeat; background-size: 100%; }
</style>
3. 적용
적용은 별 다른 것 없이 사용할 곳에다가 컴포넌트를 추가하면 된다.
<checkbox v-model="checked" label="체크박스라벨명" />
v-model 이외에도 input 이벤트를 감지하여 사용할 수도 있다.
<checkbox label="체크박스라벨명" @input="onCheckedChange" />
대신에 메소드를 정의하여 값을 받아와야 하는 단점이 있다.
[Linux] Node.js 다른 방식으로 설치하기(무설치) (0) | 2022.03.14 |
---|---|
[Vue.js] 커스텀 RadioButton 만들어 보기 (0) | 2022.02.23 |
[Webpack] JS 내용을 HTML 에 Inline 으로 넣어보자 (InlineChunkHtmlPlugin) (0) | 2022.02.16 |
[JS] A태그 내에서 Javascript 의 encodeURIComponent 사용 문제 (0) | 2022.02.15 |
[JS] Daum 우편번호찾기를 이용한 위,경도 좌표 구하기 (0) | 2022.02.08 |