개발을 진행하다 보니, 달력을 만들어야 할 날이 왔다.
개발 라이브러리로 vuetify를 사용하는데 vuetify에서 제공하는 달력은 두 종류가 있다.
하나는 달력만을 보여주는 date-picker, 캘린더의 역활을 하는 calnder, 두 종류고 캘린더까진 필요하지 않아서 date-picker을 사용했다. custom 하기가 어려웠지만 어떠한 방식으로 해냈고, 어떻게 헤딩을 했는지 써보려고 한다!
https://vuetifyjs.com/en/api/v-date-picker/
1. date-picker한글 셋팅 하기
vuetify에서 제공하는 locale이라는 속성에 KO를 넣어주면 한글 버전을 사용할 수 있지만 날짜 옆에 '일'도 함께 나와서 이걸 해결해야만 했었다. 그러던 중 이것에 관련하여 포스팅하신 개발자분의 블로그를 보게 되었고, 많은 도움을 받았었다.
참고: https://velog.io/@rkql1109/Vue-Vuetify-dialog-캘린더-ui-한글-커스텀
[Vue] Vuetify dialog 캘린더 ui, 한글 커스텀
Vuetify 다이얼로그 캘린더를 사용하다가 커스텀을 할 일이 있어서 수정을 하게 되었다. 한글버전으로 사용하기 위해 속성에 locale="ko-KR" 를 추가 했었는데 날짜 뒤에 '일' 이 붙어져 나와서 한글버
velog.io
<v-date-picker
v-model="datePicker"
color="#FF7527"
class="collector-datePicker"
no-title
next-icon="mdi-chevron-right"
prev-icon="mdi-chevron-left"
:weekday-format="getDay"
:month-format="getMonth"
:header-date-format="changeHeaderDate"
show-adjacent-months
reactive
width="100%"
show-current="none"
:events="changeDatePickerTitle"
:picker-date.sync="datePicker"
/>
<script>
export default {
name: 'CollectorMain',
data:() => ({
datePicker: (new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10),
}),
methods:{
getDay(date) {
const daysOfWeek = ['일', '월', '화', '수', '목', '금', '토'];
let week = new Date(date).getDay(date);
return daysOfWeek[week];
},
getMonth(date) {
const monthName = [ '1월','2월','3월','4월','5월','6월','7월','8월','9월','10월','11월','12월'];
let month = new Date(date).getMonth(date);
return monthName[month];
},
changeHeaderDate(){
const title = this.datePicker.split('-').join('.')
return title ;
}
}
}
</script>
Header부분 같은 경우는 기획이 선택한 날짜를 달력의 Header에 보여주길 원해서 이렇게 했지만 년도를 표시하고 싶으면
getYear(date){
let year = new Date(date).getFullYear(date)
return year +'년';
}
이렇게 해주면 된다.
2. 주말 색 변경 하기
한글 부분은 너무 옛날에 적용했던거라 참고했던 블로그 포스팅이 어땠었는지 까먹고 있었는데 내 블로그에 정리하기 위해 다시 포스팅을 확인해보니 주말 색 변경하는 부분도 블로그에 적어 놓아주셔서 참고를 했다면 조금 더 깔끔한 코드를 짤 수 있었을 텐데 란 아쉬움이 있지만 그로 인해 배운 것이 있기 때문에 기록하려고 한다!
확실히 나는 아직 많이 부족하다고 느꼈었다! 열심히 해야지!
1) 주말색을 바꾸려면 어떻게 해야 할까?
주말 색을 바꾸기 위해 내가 한 고민은, DOM에 접근해서 새로운 class를 넣어주고 그걸 보여줘야 하나? vue는 DOM에 직접 접근해서 컨트롤하는 걸 지양하는데 괜찮은가? 접근하지 않고 어떻게 할 수 있을까? css에서 해결할 수 있지 않을까?! 해서 검색을 해보았고 다음 블로그를 보았다.
참고: https://hyunning.tistory.com/entry/datepicker-주말-색상-변경 [Hyunning:06-:티스토리]
2) 해결법
그래서 css 코드에 :v-deep .v-date-picker-table.v-date-picker-table--date.theme--light > table tbody tr td:first-child button > .v-btn__content를 추가해서 스타일을 변경해 주었다. :v-deep은 나중에 다시 한번 블로그에 정리하기 위해 지금은 사용했다 란 것만 쓸 예정이다!
추후 css 가독성이 너무 떨어져 핵심 class 제외하고 나머진 지워줌으로써 조금 더 가독성 좋은 코드가 되었다고 생각하는데
.collector-datePicker .v-date-picker-table > table tbody tr td:first-child button > .v-btn__content
한글로 변경하기 할 때 참고했던 블로그 안에 &:nth-child(1)을 사용해 훨씬 가독성이 좋은 코드가 된 것을 보고 기본 베이스 쪽 공부도 열심히 해야겠다란 다짐을 다시 한번 했다.
3. pickerHeader부분에 선택한 요일 표시하기
정말 헤딩은 오래 하지 않았지만 이 방법이 맞는지에 대한 의구심이 들었던 문제였다. 디자이너가 원하는 디자인에서 달력의 헤더 부분은 선택한 날짜가 보이고 옆에 요일이 보이는 것이었는데, 같은 style이 아닌 요일은 조금 더 작고 회색의 글씨로 디자인되어 있는 것이었다.
직접 만드는 것이 아닌 라이브러리를 사용해서 쓰다 보니 어쩔 수 없이 DOM에 접근해야겠다 라는 생각이 들었다.
<v-date-picker
v-model="datePicker"
color="#FF7527"
class="collector-datePicker"
no-title
next-icon="mdi-chevron-right"
prev-icon="mdi-chevron-left"
:weekday-format="getDay"
:month-format="getMonth"
:header-date-format="changeHeaderDate"
show-adjacent-months
reactive
width="100%"
show-current="none"
:events="changeDatePickerTitle"
:picker-date.sync="datePicker"
/>
<script>
export default {
name: 'CollectorMain',
data:() => ({
datePicker: (new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10),
}),
watch:{
//datePicker가 변경되면 실행
datePicker(){
this.changeDatePickerTitle()
this.dateFormatChange()
}
},
//page가 생성될고서 DOM에 연결될때 실행
mounted(){
this.changeDatePickerTitle()
this.dateFormatChange()
},
methods:{
changeDatePickerTitle(){
const daysOfWeek = ['일요일', '월요일', '화요일', '수요일', '목요일', '금요일', '토요일'];
//선택한 날의 요일을 찾기
let week = new Date(this.datePicker).getDay(this.datePicker);
//Header에 추가해줘야하는 부모 class 찾기
const parentsClass = document.getElementsByClassName('v-date-picker-header__value')
//부모클래스 숫자만큼 실행이 됨
for(var i = 0; i < parentsClass.length; i++){
var childrenBtn = parentsClass[i].children[i].children[i]
//childrenBtn의 children의 length가 0보다 크면 element가 추가 되어있는 것이기 때문에
//안에있는 HTML만 변경
if(childrenBtn.children.length > 0){
childrenBtn.children[i].innerHTML = daysOfWeek[week]
}else{
//새로운 Span을 만들어주고, span의 스타일을 지정한다음,
//추가될 클래스 위치에 자식으로 넣어주기
let newSpan = document.createElement("span")
newSpan.innerHTML = daysOfWeek[week]
newSpan.style.color = '#c4c4c4'
newSpan.style.fontSize = '12px'
newSpan.style.paddingLeft = '4px'
childrenBtn.appendChild(newSpan)
}
}
}
}
}
</script>
처리를 해주고 나니 문제가 있었다.
달력을 넘기면 추가해준 element가 없어진다는 것이었는데, 이걸 해결해주기 위해, picker-date.sync를 바인딩시켜주어 해결했다. 그전에는 달을 옮겨도 이미 선택한 날짜로 헤더가 고정되어 있어서 지금 보고 있는 달이 어디인지를 보려면 헤더를 클릭해 달을 봐야만 했었는데, 이 처리를 해주고 나선 헤더 부분이 변경된 달로 바뀌기 때문에 더더욱 좋았다.
이 방법이 좋은 방법인지는 잘 알 수 없지만 나는 이렇게 해결을 했었다. 아직 나는 css 부분이나 js 쪽 부분이 약하지만 열심히 공부해서 좋은 개발자가 되고싶다.
'Vue' 카테고리의 다른 글
[Vue 2] vue-router 설정하기 (0) | 2023.01.30 |
---|---|
[Vue 2] axios 모듈화 하기 (0) | 2023.01.03 |
[Vue 2] vuetify icon custom 하기 (0) | 2022.09.21 |
[Vue 2] data(){return{}} 과 data:()=>({}) 의 차이 기록 (0) | 2022.08.25 |
[Vue 2] Instance Properties 추가하기(전역 속성 추가하기) (0) | 2022.08.18 |