Vue 공식 문서 기반으로 작성한 필수 스타일 가이드에 대한 내용 정리입니다 🙂
자세한 내용은 공식문서를 참고 부탁드립니다.
1. 컴포넌트의 이름은 합성어를 사용한다.
html 태그의 경우 한 단어로 태그가 구성되어 있기 때문에 충돌 방지를 위하여 컴포넌트 이름의 경우 합성어 사용을 권장하고 있습니다.
// 나쁜 예
<main>HTML 태그</main>
// HTML의 태그와 이름이 같기 때문에 충돌 문제가 생길 수 있음
export default {
name: 'main',
}
// 좋은 예
export default {
name: 'MainHome',
2. 컴포넌트의 data는 함수로 반환해야 한다.
// 나쁜 예
// 모든 인스턴스가 동일한 data를 참조
name : 'TodoList'
data: {
todos: ['할일1', '할일2']
}
따라서 아래 코드와 같이 각 컴포넌트에서 자체적으로 data를 관리하기 위해 함수 안에서 객체를 반환하여 고유한 data를 가지게 합니다.
// 좋은 예
name : 'TodoList'
data: function () {
return {
todos: ['할일1', '할일2']
}
}
3. Props는 최대한 상세히 작성합니다.
props의 타입을 미리 파악하여 컴포넌트의 사용 방법을 보다 쉽게 사용할 수 있습니다.
또한 전달 값이 설정한 타입과 다르면 경고 메시지를 출력하기 때문에 오류를 미리 방지할 수 있습니다.
// 나쁜 예
props : ['num', 'txt']
// 좋은 예
props : {
num : Number,
txt : String
}
// 좀 더 상세한 설정도 가능합니다.
props : {
num : {
type : Number,
default : 10,
},
txt : {
type : String,
default : '텍스트 props',
},
}
4. v-for를 사용 시 key를 필수로 지정해야 합니다.
서브트리 내부 컴포넌트 상태 유지를 위하여 무조건 key와 함께 사용 해야 합니다. Vue에서 구조를 예측 할 수 있게 해야 하기 때문입니다.
// 나쁜 예
<ul>
<li v-for="todo in todos">
{{ todo.text }}
</li>
</ul>
// 좋은 예
<ul>
<li
v-for="todo in todos"
:key="todo.id"
>
{{ todo.text }}
</li>
</ul>
// data 참고
data: function () {
return {
todos: [
{
id: 1,
text: '텍스트1'
},
{
id: 2,
text: '텍스트2'
}
]
}
}
5. v-if와 v-for를 동시에 사용하면 안됩니다.
// 나쁜 예
<ul>
<li
v-for="user in users"
v-if="user.isActive"
:key="user.id"
>
{{ user.name }}
</li>
</ul>
Vue에서는 v-for가 v-if보다 우선 순위가 높기 때문에 위와 같은 상황이면 반복문이 끝나고 다시 반복문을 반복하면서 v-if 조건을 체크하게 되어 성능이 떨어지게 됩니다.
따라서 예시 코드와 같이 computed를 활용하여 배열에 대한 조건을 계산하게 하면 값이 바뀔 때 즉시 렌더링 되는 부분과 더불어 효율이 좋아집니다.
// 좋은 예
<ul>
<li
v-for="user in activeUsers"
:key="user.id"
>
{{ user.name }}
</li>
</ul>
// filter를 사용하여 해당 조건의 새 배열을 반환 합니다.
computed: {
activeUsers() {
return this.users.filter(user => {
user.isActive
})
}
}
6. 컴포넌트 스타일 스코프
최상위 컴포넌트인 App의 경우 스타일에 대한 전역 설정을 하지만 다른 컴포넌트의 경우 scoped의 범위가 지정되어야 합니다.
라이브러리, 규모가 큰 프로젝트의 경우 사용하는 클래스 이름의 충돌을 방지할 수도 있습니다.
scoped 지정, BEM사용, style module 사용 등 선택하여 사용하는 것을 권유하고 있습니다.
// sopced 사용
<style scoped>
.button {
border: none;
border-radius: 2px;
}
.button-close {
background-color: red;
}
</style>
// module 사용
<template>
<button :class="[$style.button, $style.buttonClose]">X</button>
</template>
<style module>
.button {
border: none;
border-radius: 2px;
}
.buttonClose {
background-color: red;
}
</style>
// BEM 사용
<style>
.c-Button {
border: none;
border-radius: 2px;
}
.c-Button--close {
background-color: red;
}
</style>
7. private 속성 이름 규칙
mixin이나 플러그인 등 개인 속성에 대한 규칙의 접두사로 $_ 를 함께 사용하는 것을 권장합니다. 또한 충돌이 생길 만한 이름은 사용하지 않습니다.
Vue에서는 _(언더바) 접두사를 사용하여 개인 속성을 정의하기 때문에 인스턴스 속성의 이름을 정의 할 때 접두사로 사용하지 않는 것이 좋습니다. 현재 사용하고 있지 않더라도 이후 버전에서 추가 될 수 있기 때문에 권장하지 않습니다.
또한 $의 경우도 Vue에서 사용자에게 노출되는 특수 인스턴스의 속성이기 때문에 개인적인 속성의 접두사로 사용하는 것은 좋지 않습니다.
// 나쁜 예
var myGreatMixin = {
methods: {
_update: function () { // _ 언더바 사용
},
$update: function () { // $ 사용
},
$_update:: function () { // 단순한 이름을 사용하여 충돌 가능성 (update)
},
}
}
// 좋은 예
var myGreatMixin = {
methods: {
$_myGreatMixin_update: function () { // 충돌이 나지 않는 이름 및 $_ 접두사 사용
}
}
}
// 조금 더 좋은 예
var myGreatMixin = {
methods: {
publicMethod() {
myPrivateFunction()
}
}
}
function myPrivateFunction() {
// ...
}
export default myGreatMixin