Vue 스타일 가이드 3
Vue 스타일 가이드 3편입니다.
2편 : http://gameb.co.kr/vue-스타일-가이드-2/
★ : 필수
☆ : 매우 추천
○ : 추천
X : 주의 요함
21.속성 값에 따옴표 ☆
속성 값은 항상 따옴표를 사용합니다.
나쁨
<input type=text>
<AppSidebar :style={width:sidebarWidth+'px'}>
좋음
<input type="text">
<AppSidebar :style="{ width: sidebarWIdth + 'px' }">
22.축약형 지시어 ☆
v-bind, @, # 와 같은 축약형 지시어는 항상 사용하거나 사용하지 않는게 좋습니다.
나쁨
<input
v-bind:value="newTodoNext"
:placeholder="newTodoInstructions"
>
<input
v-on:input="onInput"
@focus="onFocus"
>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<template #footer>
<p>Here's some contact info</p>
</template>
좋음
<input
:value="newTodoText"
:placeholder="newTodoInstructions"
>
<input
v-bind:value="newTodoText"
v-bind:placeholder="newTodoInstructions"
>
<input
@input="onInput"
@focus="onFocus"
>
<input
v-on:input="onInput"
v-on:focus="onFocus"
>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
23.컴포넌트/인스턴스의 옵션 순서 ○
컴포넌트/인스턴스 옵션의 순서는 언제나 일정한 순서로 정렬 되어야 합니다.
1.사이드이펙트 – 컴포넌트 외부에 효과가 미치는 옵션
- el
2.전역 인지 – 컴포넌트 외부에 필요한 옵션
- name
- parent
3.컴포넌트 유형 – 컴포넌트의 유형을 바꾸는 옵션
- functional
4.템플릿 변경자 – 템플릿 컴파일 변경 옵션
- delimiters
- comments
5.템플릿 의존성 – 템플릿에 이용되는 요소들을 지정하는 옵션
- components
- directives
- filters
6.컴포지션 – 다른 컴포넌트의 속성을 가져와 합치는 옵션
- extends
- mixins
7.인터페이스 – 컴포넌트의 인터페이스를 지정하는 옵션
- inheritAttrs
- model
- props / propsData
8.지역 상태 – 반응적인 지역 속성들을 설정하는 옵션
- data
- computed
9.이벤트 – 반응적인 이벤트 옵션
- watch
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- activated
- deactived
- beforeDestory
- destroyed
10.비반응적 속성 – 반응과 상관업는 옵션
- methods
11.렌더링 – 컴포넌트의 출력 옵션
- template / render
- renderError
24.엘리먼트 속성 순서
1.정의 – 컴포넌트 옵션을 제공하는 속성
- is
2.리스트 렌더링 – 같은 엘리먼트를 여러 개 생성하는 속성
- v-for
3.조건부 렌더링 – 렌더링 여부를 결정하는 속서
- v-if
- v-else-if
- v-else
- v-show
- v-cloak
4.렌더 변경자 – 렌더링 방식을 변경하는 속성
- v-pre
- v-once
5.전역 인지 – 컴포넌트의 외부 속성
- id
6.유일한 속성 – 유일한 값을 가진 속성
- ref
- key
- slot
7.양방향 바인딩 – 바인딩과 이벤트를 결합
- v-model
8.이벤트 – 이벤트 리스너 속성
- v-on
9.내용 – 엘리먼트의 내용 변경 속성
- html
- text
25.컴포넌트/인스턴스 옵션간 빈 줄 ○
가독성을 위해 속성 사이에 빈 줄을 추가할 수 있습니다.
좋음
props : {
value : {
type : String,
required : true
},
focused : {
type : Boolean,
default : false
},
label : String,
icon : String
},
computed : {
formattedValue : function () {
//...
},
inputClassed : function ) {
//...
}
}
props : {
value : {
type : String,
required : true
},
focused : {
type : Boolean,
default : false
},
label : String,
icon : String
},
computed : {
formattedValue : function () {
//...
},
inputClassed : function ) {
//...
}
}
26.싱글 파일 컴포넌트 최상위 엘리먼트 순서
style 엘리먼트는 마지막에 배치하는게 좋습니다.
나쁨
<style> /*...*/ </style>
<script> /*...*/ </script>
<template> /*...*/ </template>
<!-- ComponentA.vue -->
<script> /*...*/ </script>
<template> /*...*/ </template>
<style> /*...*/ </style>
<!-- ComponentB.vue -->
<template> /*...*/ </template>
<script> /*...*/ </script>
<style> /*...*/ </style>
좋음
<!-- ComponentA.vue -->
<script> /*...*/ </script>
<template> /*...*/ </template>
<style> /*...*/ </style>
<!-- ComponentB.vue -->
<script> /*...*/ </script>
<template> /*...*/ </template>
<style> /*...*/ </style>
<!-- ComponentA.vue -->
<template> /*...*/ </template>
<script> /*...*/ </script>
<style> /*...*/ </style>
<!-- ComponentB.vue -->
<template> /*...*/ </template>
<script> /*...*/ </script>
<style> /*...*/ </style>
26.key 가 없는 v-if / v-if-else / v-else X
요소 유형이 동일한 경우 key와 함께 사용하는 것이 좋습니다. (v-if, v-else)
나쁨
<div v-if="error">
Error : {{ error }}
</div>
<div v-else>
{{ results }}
</div>
좋음
<div
v-if="error"
key="search-status"
>
Error : {{ Error }}
</div>
<div
v-else
key="search-results"
>
{{ results }}
</div>
27.scoped에서 엘리먼트 선택자 사용 X
태그 선택자보다 클래스 선택자를 사용합니다.
나쁨
<template>
<button>X</button>
</template>
<style scoped>
button {
background-color:red;
}
</style>
좋음
<template>
<button class="btn btn-close">X</button>
</template>
<style scoped>
.btn-close {
background-color:red;
}
</style>
28.부모 자식간 의사소통 X
this.$parent 보다는 emit을 사용하는게 좋습니다.
나쁨
Vue.component('TodoItem', {
props : {
todo : {
type : Object,
required : true
}
},
template : '<input v-model="todo.text">'
})
Vue.component('TodoItem', {
props : {
todo : {
type : Object,
required : true
}
},
methods : {
removeTodo () {
var vm = this
vm.$parent.todos = vm.$parent.todos.filter(function (todo) {
return todo.id !== vm.todo.id
})
}
},
templte : `
<span>
{{ todo.text }}
<button @click="removeTodo">
X
</button>
</span>
`
})
좋음
Vue.component('TodoItem', {
props: {
todo: {
type: Object,
required: true
}
},
template: `
<input
:value="todo.text"
@input="$emit('input', $event.target.value)"
>
`
})
Vue.component('TodoItem', {
props: {
todo: {
type: Object,
required: true
}
},
template: `
<span>
{{ todo.text }}
<button @click="$emit('delete')">
X
</button>
</span>
`
})
29.전역 상태 관리
전역 상태는 this.$root, global event bus 보다는 Vuex를이용하는 것이 좋습니다.
나쁨
new Vue({
data : {
todos : []
},
created : function() {
this.$on('remove-todo',this.removeTodo)
},
methods : {
removeTodo : function (todo) {
var todoIdToRemove = todo.id
this.todos = this.todos.filter(function (todo) {
return todo.id !== todoIdToRemove
})
}
}
})
좋음
// store/modules/todos.js
export default {
state : {
list : []
},
mutations : {
REMOVE_TODO (state,todoId) {
state.list = state.list.filter(todo => todo.id ! == todoId)
}
},
actions : {
removeTodo ({ commit, state }, todo) {
commit('REMOVE_TODO', todo_id)
}
}
}
<!-- TodoItem.vue -->
<template >
<span>
{{ todo.text }}
<button @click="removeTodo(todo)">
X
</button>
</span>
</template>
<script>
import { mapActions } from 'vuex'
export default {
props : {
todo : {
type : Object,
required : true
}
},
methods : mapActions(['removeTodo'])
}
</script>