Vue.js 에서 권장하는 스타일 가이드. 코딩 컨벤션 같은 거랄까..
가이드 하는 내용 중 필수와 매우추천함 항목에 대해 설명한다.
1. 컴포넌트 이름에 합성어 사용
root 컴포넌트인 App 컴포넌트를 제외하고는 컴포넌트의 이름은 항상 "합성-어"를 사용해야 한다.
모든 HTML 엘리먼트의 이름은 한 단어로 표현되기 때문에, 충돌을 방지하려면 컴포넌트를 잘 설명할 수 있는 하이픈으로 구분된 합성어를 사용하는것이 좋다.
2. 컴포넌트 데이터
컴포넌트 데이터는 함수여야 한다.
한 컴포넌트에서 data 프로퍼티를 사용할 때, 그 값은 무조건 한 객체를 리턴하는 함수여야 한다.
함수가 아닌 그냥 일반 객체일 경우, 컴포넌트를 두 영역에 렌더링 시 같은 data 객체를 참조하게 되어, 두 컴포넌트가 같은 값을 공유하게 되는 문제가 발생한다. (의도적인 거라면 할말없지만, mvvm 패턴을 따르지 않는 잘못된 방식이다.)
따라서 각 사용처마다 독립적인 data 객체를 가져야 하므로 꼭 함수로 정의하여 리터럴 객체를 리턴하도록 구현해야 한다.
Bad
Vue.component('some-comp', { |
export default { |
3. Props 정의
Prop 정의는 가능한 가장 자세히 기술해야 한다.
최소 type 이라도 기술하자.
Bad
// This is only OK when prototyping |
4. v-for에 key 지정
v-for 사용시 항상 key를 지정해라.
내부 컴포넌트의 하위 트리의 상태를 유지하기 위해 key 가 필요하다.
Vue.js 는 가상 돔 렌더링을 한다.
v-for 와 같은 디렉티브는 바인딩 된 배열에 따라 내용이 그려진다.
배열에 아이템이 하나라도 추가되면 전체 내용을 다시 그려야 하는 비싼 연산이 될 수 있다.
이련 경우를 방지하고자, 각 아이템의 key를 알려주면 정확한 비교가 가능하므로, 가상돔 업데이트 연산 과정이 명확하고 빠르게 수행되어 불필요한 업데이트를 방지 할 수 있다.
Bad
<ul> |
5. v-if 와 v-for 를 동시에 사용하지 마세요
Vue가 디렉티브를 처리하는 과정에서, v-for 가 v-if 보다 우선순위가 더 높다.
따라서 아래와 같은 템플릿이
<ul> |
이렇게 해석 될 수 있다.
this.users.map(function (user) { |
따라서 users 의 일부분만 렌더링 하려는 의도임에도, active user 가 변경되었는지 여부에 관계없이, 리렌더링 할때마다 전체 users 목록을 항상 순회해야 한다.
그 대신 아래와 같이 계산된 프로퍼티를 순회해라.
computed: { |
<ul> |
이렇게 구현하면 아래와 같은 이점을 얻는다.
- 필터링 된 리스트는 users 배열에 active 변경사항이 있는 경우만 다시 계산되므로 필터링이 훨씬 효과적이다.
- v-for="users in activeUsers" 를 사용하면, 렌더링 동안에 active users 만 순회하므로 렌더링이 훨씬 효과적이다.
- 로직과 화면 영역이 분리되어, 유지관리가 훨씬 수월 해 진다.
Bad
<ul> |
<ul> |
6. 컴포넌트 스타일 스코프
최상단 App 컴포넌트와 layout 관련 컴포넌트의 스타일은 전역이 될 수도 있지만, 다른 모든 컴포넌트듸 스타일은 항상 scoped 여야 한다.
이거는 단순히 싱글 파일 컴포넌트에 대한 얘기이다. 항상 scoped 속성을 요구하는것이 아니다. 스코핑은 CSS module 을 통해 정의될 수도있고, BEM 과 같은 클래스-기반 방법도 있다.
컴포넌트 라이브러리들은 scoped 속성을 사용하는 대신 클래스-기반 전략을 취해야 한다.
클래스-기반 전략을 취하면 내부 스타일을 재정의 하는것이 더 쉬우며, 사람이 읽을 수 있는 클래스 이름을 사용하면(높은 특정도를 가지지는 않지만) 충돌을 일으키지는 않는다.
만약 다른 개발자들과, 외부 다른 서드파티 HTML/CSS 를 포함한 큰 프로젝트를 개발한다고 한다면, 일관된 스코핑은 스타일이 의도된 컴포넌트에만 적용되도록 확신할 수 있다.
scpoed 속성 외에도, 유니크한 클래스이름 사용은 서드파티와 충돌을 일으키지 않는데 도움을 받을 수 있다.
예를들면 많은 프로젝트가 button, btn, icon 같은 클래스 이름을 사용하는데,
굳이 BEM 스타일을 사용하지 않아도, 프로젝트나 및 컴포넌트 별로 ButtonClose-icon 같은 접두사를 추가하면 충돌을 방지할 수 있는 보호장치를 마련할 수 있다.
Bad
<template> |
Good
<template> |
<template> |
<template> |
7. Private 속성 이름
plugin, mixin 등 을 정의할 때 private 속성은 항상 $_ 접두어를 사용하여 정의해라.
_ 접두어는 Vue 에서 private 속성들을 정의하는데 사용하므로, _ 접두어 사용은 vue 인스턴스의 속성을 오버라이딩 할 수 있는 위험성이 있다. 만약 그 속성명이 사용되지 않음을 확인했다 치더라도, 다음 버전에서 충돌이 일어나지 않을것이라는 보장이 없다.
$ 접두어는 Vue 에코시스템 안에서 사용자에게 노출시키려는 의미를 가진 특별한 속성이다. 따라서 $ 접두어 사용도 적절치 않다.
대신 두 접두어를 혼합한 $_ 접두어를 추천한다. 컨벤션으로 $_ 접두어는 사용자 정의 private 속성을 보장하여 Vue 와 충돌이 없다.
Bad
var myGreatMixin = { |
var myGreatMixin = { |
var myGreatMixin = { |
var myGreatMixin = { |