Vue.js 에서 권장하는 스타일 가이드. 코딩 컨벤션 같은 거랄까..



가이드 하는 내용 중 필수매우추천함 항목에 대해 설명한다.


1. 컴포넌트 이름에 합성어 사용

root 컴포넌트인 App 컴포넌트를 제외하고는 컴포넌트의 이름은 항상 "합성-어"를 사용해야 한다.

모든 HTML 엘리먼트의 이름은 한 단어로 표현되기 때문에, 충돌을 방지하려면 컴포넌트를 잘 설명할 수 있는 하이픈으로 구분된 합성어를 사용하는것이 좋다.

Bad

Vue.component('todo', {
// ...
})
export default {
name: 'Todo',
// ...
}

Good

Vue.component('todo-item', {
// ...
})
export default {
name: 'TodoItem',
// ...
}

2. 컴포넌트 데이터

컴포넌트 데이터는 함수여야 한다.
한 컴포넌트에서 data 프로퍼티를 사용할 때, 그 값은 무조건 한 객체를 리턴하는 함수여야 한다.

함수가 아닌 그냥 일반 객체일 경우, 컴포넌트를 두 영역에 렌더링 시 같은 data 객체를 참조하게 되어, 두 컴포넌트가 같은 값을 공유하게 되는 문제가 발생한다. (의도적인 거라면 할말없지만, mvvm 패턴을 따르지 않는 잘못된 방식이다.)

따라서 각 사용처마다 독립적인 data 객체를 가져야 하므로 꼭 함수로 정의하여 리터럴 객체를 리턴하도록 구현해야 한다.

Bad

Vue.component('some-comp', {
data: {
foo: 'bar'
}
})
export default {
data: {
foo: 'bar'
}
}

Good

Vue.component('some-comp', {
data: function () {
return {
foo: 'bar'
}
}
})
// In a .vue file
export default {
data () {
return {
foo: 'bar'
}
}
}
// It's OK to use an object directly in a root
// Vue instance, since only a single instance
// will ever exist.
new Vue({
data: {
foo: 'bar'
}
})


3. Props 정의

Prop 정의는 가능한 가장 자세히 기술해야 한다.
최소 type 이라도 기술하자.

Bad

// This is only OK when prototyping
props: ['status']

Good

props: {
status: String
}
// Even better!
props: {
status: {
type: String,
required: true,
validator: function (value) {
return [
'syncing',
'synced',
'version-conflict',
'error'
].indexOf(value) !== -1
}
}
}

4. v-for에 key 지정

v-for 사용시 항상 key를 지정해라.
내부 컴포넌트의 하위 트리의 상태를 유지하기 위해 key 가 필요하다. 

Vue.js 는 가상 돔 렌더링을 한다.
v-for 와 같은 디렉티브는 바인딩 된 배열에 따라 내용이 그려진다.
배열에 아이템이 하나라도 추가되면 전체 내용을 다시 그려야 하는 비싼 연산이 될 수 있다.
이련 경우를 방지하고자, 각 아이템의 key를 알려주면 정확한 비교가 가능하므로, 가상돔 업데이트 연산 과정이 명확하고 빠르게 수행되어 불필요한 업데이트를 방지 할 수 있다.

Bad

<ul>
<li v-for="todo in todos">
{{ todo.text }}
</li>
</ul>

Good

<ul>
<li
v-for="todo in todos"
:key="todo.id"
>
{{ todo.text }}
</li>
</ul>

5. v-if 와 v-for 를 동시에 사용하지 마세요

Vue가 디렉티브를 처리하는 과정에서, v-for 가 v-if 보다 우선순위가 더 높다.
따라서 아래와 같은 템플릿이
<ul>
<li
v-for="user in users"
v-if="user.isActive"
:key="user.id"
>
{{ user.name }}
<li>
</ul>
이렇게 해석 될 수 있다.
this.users.map(function (user) {
if (user.isActive) {
return user.name
}
})

따라서 users 의 일부분만 렌더링 하려는 의도임에도, active user 가 변경되었는지 여부에 관계없이, 리렌더링 할때마다 전체 users 목록을 항상 순회해야 한다.
그 대신 아래와 같이 계산된 프로퍼티를 순회해라.
computed: {
activeUsers: function () {
return this.users.filter(function (user) {
return user.isActive
})
}
}
<ul>
<li
v-for="user in activeUsers"
:key="user.id"
>
{{ user.name }}
<li>
</ul>
이렇게 구현하면 아래와 같은 이점을 얻는다.
  • 필터링 된 리스트는 users 배열에 active 변경사항이 있는 경우만 다시 계산되므로 필터링이 훨씬 효과적이다.
  • v-for="users in activeUsers" 를 사용하면, 렌더링 동안에 active users 만 순회하므로 렌더링이 훨씬 효과적이다.
  • 로직과 화면 영역이 분리되어, 유지관리가 훨씬 수월 해 진다.

Bad

<ul>
<li
v-for="user in users"
v-if="user.isActive"
:key="user.id"
>
{{ user.name }}
<li>
</ul>
<ul>
<li
v-for="user in users"
v-if="shouldShowUsers"
:key="user.id"
>
{{ user.name }}
<li>
</ul>

Good

<ul>
<li
v-for="user in activeUsers"
:key="user.id"
>
{{ user.name }}
<li>
</ul>
<ul v-if="shouldShowUsers">
<li
v-for="user in users"
:key="user.id"
>
{{ user.name }}
<li>
</ul>

6. 컴포넌트 스타일 스코프

최상단 App 컴포넌트와 layout 관련 컴포넌트의 스타일은 전역이 될 수도 있지만, 다른 모든 컴포넌트듸 스타일은 항상 scoped 여야 한다.

이거는 단순히 싱글 파일 컴포넌트에 대한 얘기이다. 항상 scoped 속성을 요구하는것이 아니다. 스코핑은 CSS module 을 통해 정의될 수도있고, BEM 과 같은 클래스-기반 방법도 있다.

컴포넌트 라이브러리들은  scoped 속성을 사용하는 대신 클래스-기반 전략을 취해야 한다.
클래스-기반 전략을 취하면 내부 스타일을 재정의 하는것이 더 쉬우며, 사람이 읽을 수 있는 클래스 이름을 사용하면(높은 특정도를 가지지는 않지만) 충돌을 일으키지는 않는다.

만약 다른 개발자들과, 외부 다른 서드파티 HTML/CSS 를 포함한 큰 프로젝트를 개발한다고 한다면, 일관된 스코핑은 스타일이 의도된 컴포넌트에만 적용되도록 확신할 수 있다.

scpoed 속성 외에도, 유니크한 클래스이름 사용은 서드파티와 충돌을 일으키지 않는데 도움을 받을 수 있다. 

예를들면 많은 프로젝트가 button, btn, icon 같은 클래스 이름을 사용하는데, 
굳이 BEM 스타일을 사용하지 않아도, 프로젝트나 및 컴포넌트 별로 ButtonClose-icon 같은 접두사를 추가하면 충돌을 방지할 수 있는 보호장치를 마련할 수 있다.

Bad

<template>
<button class="btn btn-close">X</button>
</template>

<style>
.btn-close {
background-color: red;
}
</style>

Good

<template>
<button class="button button-close">X</button>
</template>

<!-- Using the `scoped` attribute -->
<style scoped>
.button {
border: none;
border-radius: 2px;
}

.button-close {
background-color: red;
}
</style>
<template>
<button :class="[$style.button, $style.buttonClose]">X</button>
</template>

<!-- Using CSS modules -->
<style module>
.button {
border: none;
border-radius: 2px;
}

.buttonClose {
background-color: red;
}
</style>
<template>
<button class="c-Button c-Button--close">X</button>
</template>

<!-- Using the BEM convention -->
<style>
.c-Button {
border: none;
border-radius: 2px;
}

.c-Button--close {
background-color: red;
}
</style>


7. Private 속성 이름

plugin, mixin 등 을 정의할 때 private 속성은 항상 $_ 접두어를 사용하여 정의해라.

_ 접두어는 Vue 에서 private 속성들을 정의하는데 사용하므로, _ 접두어 사용은 vue 인스턴스의 속성을 오버라이딩 할 수 있는 위험성이 있다. 만약 그 속성명이 사용되지 않음을 확인했다 치더라도, 다음 버전에서 충돌이 일어나지 않을것이라는 보장이 없다.

$ 접두어는 Vue 에코시스템 안에서 사용자에게 노출시키려는 의미를 가진 특별한 속성이다. 따라서 $ 접두어 사용도 적절치 않다.

대신 두 접두어를 혼합한 $_ 접두어를 추천한다. 컨벤션으로 $_ 접두어는 사용자 정의 private 속성을 보장하여 Vue 와 충돌이 없다.


Bad

var myGreatMixin = {
// ...
methods: {
update: function () {
// ...
}
}
}
var myGreatMixin = {
// ...
methods: {
_update: function () {
// ...
}
}
}
var myGreatMixin = {
// ...
methods: {
$update: function () {
// ...
}
}
}
var myGreatMixin = {
// ...
methods: {
$_update: function () {
// ...
}
}
}

Good

var myGreatMixin = {
// ...
methods: {
$_myGreatMixin_update: function () {
// ...
}
}
}






서론

일반적으로 디스플레이는 1초에 화면을 60번 그린다. 

디스플레이가 1초에 60번 바뀌는데 웹페이지가 1초에 10번 그려진다면, 사용자는 페이지가 느리다고 느낀다. 우리는 이런 현상을 Jank 라고 부른다.

그렇다면 최적화가 필요한데, 웹페이지 렌더링을 최적화 한다는 것은 브라우저가 1초에 60번 렌더링 할 수 있도록 하면 된다.

웹페이지를 회작화 하기 위해 느린 부분을 찾아서 개선해야 한다. 어떤 부분이 느린지를 찾으려면 웹페이지가 화면을 어떻게 그리는지를 알아야 한다.




브라우저 렌더링이란?

사용자로부터 요청받은 내용을 브라우저 화면에 표시하는 일.

주로 크롬, 사파리, 파이어폭스, IE 브라우저가 있는데, 각 브라우저 마다 엔진이 다르므로, 용어나 렌더링 결과가 다르게 보이는 경우가 있다. (일명 브라우저 호환문제 라고 함)

브라우저 렌더링 엔진

Webkit (웹킷)

사피리와 크롬 브라우저가 사용중인 엔진이다. 최초 리눅스 플렛폼에서 동작하기 위해 제작된 오픈소스 엔진인데 애플이 맥과 윈도우에 사파리 브라우저를 지원하기 위해 수정을 가했다. http://webkit.org

Gecko (게코)

파이어폭스 브라우저가 사용중인 엔진 이름이다.


브라우저 렌더링 과정


brouser3



DOM트리는 HTML 구조를 있는 그대로 표현하는 트리라면
렌더트리는 스타일 정보를 더한, 즉 생상 또는 면적과 같은 시각적 속성이 있는 사갈형을 포함하고 있는데, 정해진 순서대로 화면서 표시되는 트리이다.
렌터트리 생성이 끝나면, 배치가 시작되는데 이것은 각 노드가 화면의 정확한 위치에 표시되는 것을 의미한다.


렌더링 엔진은 좀 더 나은 사용자 경험을 위해 가능하면 빠르게 내용을 표시하는데,
모든 HTML을 파싱할 때까지 기다리지 않고 배치와 그리기 과정을 시작한다. 네트워크로부터 나머지 내용이 전송되기를 기다리는 동시에 받은 내용의 일부를 먼저 화면에 표시한다.
brouser9

렌더링 엔진 용어

* layout(웹킷), reflow (게코): 브라우저가 요소를 화면에 배치하는 일.
* attachment(웹킷): 렌더트리를 생성하기위해 DOM 노드와 시각정보를 연결하는 과정.


스크립트와 스타일 시트의 진행 순서

스크립트

웹은 파싱과 실행이 동시에 수행되는 동기화(synchronous) 모델이다. 웹 페이지 제작자는 파서가 <script> 태그를 만나면 즉시 파싱하고 실행하기를 기대한다. HTML4에서는 스크립트가 실행되는 동안 문서의 파싱을 중단된다. 스크립트가 외부에 있는 경우 우선 네트워크로부터 자원을 가져와야 하는데 이 또한 실시간으로 처리되고 자원을 받을 때까지 파싱은 중단된다.
하지만 HTML5는 스크립트를 비동기(asynchronous)로 처리하는 속성을 추가했기 때문에, 웹 페이지 제작자는 스크립트를 "defer"로 표시해서 HTML 파싱을 중단하지 않을 수 있다. 문서 파싱이 완료된 이후에 스크립트가 실행된다 별도의 맥락에 의해 파싱되고 실행된다.

스타일 시트

이론적으로 스타일 시트는 DOM 트리를 변경하지 않기 때문에 문서 파싱을 기다리거나 중단 할 이유가 없다. 그러나 스크립트가 문서를 파싱하는동안 스타일 정보를 요청하는 경우라면 문제가 된다. 스타일이 파싱되지 않은 상태라면 스크립트는 잘못된 결과를 내 놓기 때문에 많은 문제를 야기한다. 

파이어폭스는 아직 로드중이거나 파싱중인 스타일 시트가 있는 경우 모든 스크립트 실행을 중단한다.
웹킷은 로드되지 않은 스타일 시트 가운데 문제가 될만한 속성이 있을 때만 스크립트 실행을 중단한다.



DOM 트리와 렌더 트리의 관계

렌더러는 DOM 요소에 부합하지만 1:1 로 대응하는 관계는 아니다. 예를들어 "head" 요소와 같은 비시각적 DOM 요소는 렌더 트리에 추가되지 않는다. 또한 display: none 도 마찬가지 이다.

brouser13






















문제


숫자 N을 제곱수의 합으로 표현하고자 할 때, 사용해야 하는 제곱 수의 최소 개수를 출력하는 프로그램을 작성하시오. 예를 들어, 숫자 45를 제곱수의 합으로 표현하고자 할 때 필요한 제곱 수의 최소 개수는 2개이며, 이는 다음과 같다.

45 = 3^2 + 6^2

 

입력


첫 번째 줄에 N이 주어진다. ( 1 ≤ N ≤ 100,000 )  

출력


필요한 제곱 수의 최소 개수를 출력한다.

 

예제 입력

45

예제 출력

2

 

예제 입력

38

예제 출력

3

 



문제풀이

https://github.com/JK921/icandoit/blob/develop/multicampus/src/Solution07.java



'스터디 > 알고리즘 문제풀이' 카테고리의 다른 글

[이러닝] 직사각형배치의경우의수  (0) 2019.01.20
[이러닝] 버튼누르기  (0) 2019.01.20
[이러닝] 카드놀이  (0) 2019.01.20
[이러닝] 구슬게임  (0) 2019.01.20
[이러닝] 직사각형의합  (1) 2019.01.20

문제


2 x N 직사각형 모양의 칸이 있다. 이를 2 x 1 모양의 타일로 가득 채우려 한다. 가능한 경우의 수를 출력하는 프로그램을 작성하시오. 단, 가능한 경우의 수가 매우 많을 수 있으므로, 그 경우의 수를 1,000,007 로 나눈 나머지를 출력한다.

예를 들어, N = 3 일 경우에는 다음 세 가지의 가능한 경우가 존재한다.

alt text

 

입력


첫 번째 줄에 N이 주어진다. ( 1 ≤ N ≤ 100 )  

출력


가능한 경우의 수를 1,000,007 로 나눈 나머지를 출력한다.

 

예제 입력

3

예제 출력

3

 

예제 입력

8

예제 출력

34

 

예제 입력

37

예제 출력

87896

 



문제풀이

https://github.com/JK921/icandoit/blob/develop/multicampus/src/Solution06.java


'스터디 > 알고리즘 문제풀이' 카테고리의 다른 글

[이러닝] 제곱수의합  (0) 2019.01.20
[이러닝] 버튼누르기  (0) 2019.01.20
[이러닝] 카드놀이  (0) 2019.01.20
[이러닝] 구슬게임  (0) 2019.01.20
[이러닝] 직사각형의합  (1) 2019.01.20

문제


철수에게는 빨간색, 초록색, 파란색 세 개의 버튼이 있다. 버튼 하나를 누를 때 마다 특정 점수를 얻을 수 있으며, 철수는 1초에 한 번씩 버튼을 누를 수 있다. 물론, 특정 시간에는 세 개의 버튼 중에서 한 개의 버튼만을 누를 수 있다. 각 시간마다 특정 버튼을 눌렀을 때 얻는 점수는 모두 다를 수 있다. 예를 들어, 시간 1에 빨간색, 초록색, 파란색 버튼에 대한 점수가 3, 5, 7 로 주어질 수 있다. 이 경우에는 파란색을 누르는 것이 점수를 가장 많이 얻을 수 있다. 물론, 시간 2에 각 버튼에 대한 점수는 또 다를 수 있다. 버튼을 누를 때에는 한 가지 규칙이 있는데, 연속하여 색깔이 같은 버튼을 두 번 누를 수 없다는 것이다. 예를 들어, 시간 1에 초록색 버튼을 눌렀다면, 시간 2에는 초록색 버튼을 누를 수 없다. 이와 같은 규칙으로 각 시간마다 버튼을 누른다고 할 때, 철수가 얻을 수 있는 점수의 최댓값을 출력하는 프로그램을 작성하시오.

 

입력


첫 번째 줄에 철수에게 주어진 시간 N이 주어진다. ( 1 ≤ N ≤ 100,000 ) 두 번째 줄부터 N개의 시간에 대하여 빨간색, 초록색, 파란색 버튼을 눌렀을 때 얻을 수 있는 점수가 주어진다.

 

출력


철수가 얻을 수 있는 점수의 최댓값을 출력한다.

 

예제 입력

3
27 8 28
18 36 40
7 20 8

예제 출력

87





문제풀이

https://github.com/JK921/icandoit/blob/develop/multicampus/src/Solution05.java


'스터디 > 알고리즘 문제풀이' 카테고리의 다른 글

[이러닝] 제곱수의합  (0) 2019.01.20
[이러닝] 직사각형배치의경우의수  (0) 2019.01.20
[이러닝] 카드놀이  (0) 2019.01.20
[이러닝] 구슬게임  (0) 2019.01.20
[이러닝] 직사각형의합  (1) 2019.01.20

문제


N개의 카드가 주어지고, 각각은 자연수의 점수를 가진다. 철수는 이제 이 카드를 가져감으로써 카드에 적혀있는 수 만큼의 점수를 얻는다. 단, 카드를 가져갈 때 한가지 규칙이 있는데, 이는 연속하여 3개의 카드는 가져갈 수 없다는 것이다. 예를 들어, 6개의 카드 “1 3 5 2 7 3”가 주어질 경우, 3+5+7+3 = 18 만큼의 점수를 얻는 것이 최대이다. N개의 카드가 주어질 때, 얻을 수 있는 점수의 최댓값을 출력하는 프로그램을 작성하시오.

 

입력


첫 번째 줄에 N이 주어진다. ( 1 ≤ N ≤ 100,000 ) 두 번째 줄에 N개의 숫자가 주어지며, 이는 각 카드의 점수를 나타낸다.  

출력


얻을 수 있는 점수의 최댓값을 출력한다.

 

예제 입력

6
1 3 5 2 7 3

예제 출력

18

 


문제풀이

https://github.com/JK921/icandoit/blob/develop/multicampus/src/Solution04.java



'스터디 > 알고리즘 문제풀이' 카테고리의 다른 글

[이러닝] 직사각형배치의경우의수  (0) 2019.01.20
[이러닝] 버튼누르기  (0) 2019.01.20
[이러닝] 구슬게임  (0) 2019.01.20
[이러닝] 직사각형의합  (1) 2019.01.20
[이러닝] 숫자만들기  (1) 2019.01.20

문제


철수와 영희는 구슬 게임이 구슬 게임을 하려 한다. 이 구슬 게임의 규칙은 다음과 같다.

  1. 철수와 영희는 번갈아가며 구슬을 가져간다. 맨 처음에는 철수가 구슬을 가져간다.
  2. 구슬을 가져갈 때에는, 최소 1개에서 최대 3개까지 구슬을 가져갈 수 있다.
  3. 가져갈 구슬이 없는 사람이 진다.

예를 들어 5개의 구슬이 있다고 하자. 여기서 철수가 1개의 구슬을 가져가고, 영희가 3개의 구슬을 가져간 후, 철수가 마지막으로 1개의 구슬을 가져갔다고 가정하면 이 게임의 승자는 철수가 된다. 물론, 각자가 어떻게 구슬을 가져가느냐에 따라 승패가 달라질 수 있다. 철수와 영희는 이기기 위해서 <b>최선을 다해서 게임을 플레이 한다.</b> n개의 구슬을 시작으로 게임을 진행한다고 할 때, 철수가 이 게임을 이길 수 있다면 YES, 그렇지 않다면 NO를 출력하는 프로그램을 작성하시오.

 

입력


첫째 줄에 전체 구슬의 개수n 이 주어진다. (0 ≤ n ≤ 1,000,000)  

출력


첫째 줄에 철수가 이길 수 있으면 YES, 그렇지 않으면 NO를 출력한다.

 

예제 입력

3

예제 출력

YES

 

예제 입력

5

예제 출력

YES

 

예제 입력

191124

예제 출력

NO

 



문제풀이

https://github.com/JK921/icandoit/blob/develop/multicampus/src/Solution03.java





'스터디 > 알고리즘 문제풀이' 카테고리의 다른 글

[이러닝] 버튼누르기  (0) 2019.01.20
[이러닝] 카드놀이  (0) 2019.01.20
[이러닝] 직사각형의합  (1) 2019.01.20
[이러닝] 숫자만들기  (1) 2019.01.20
[백준 2157][DP] 여행  (0) 2018.12.04

문제


N x M 의 직사각형이 주어지며, 각 칸에는 정수가 들어있다. 이제 Q개의 질문에 대하여 답을 해야 하며, 각각의 질문은 (a, b)부터 (c, d)까지의 직사각형에 들어있는 정수의 합을 묻는다. 예를 들어, 다음과 같이 5 x 5 의 직사각형이 주어질 때, (1, 2) 부터 (3, 3) 까지의 직사각형에 들어있는 정수의 합은 26 이다.

alt text

 

입력


첫 번째 줄에 N, M, Q가 주어진다. ( 1 ≤ N, M ≤ 1,000, 1 ≤ Q ≤ 1,000,000 ) 두 번째 줄부터 N x M 직사각형이 주어진다. 직사각형 안의 숫자 S는 -100이상 100이하이다. 그 후 Q개의 질문이 주어진다. 각각의 질문은 “a b c d” 로 이루어 져 있으며, 이는 (a, b) 부터 (c, d) 까지의 직사각형에 들어있는 정수의 합을 묻는다. (1 ≤ a,c ≤ N, 1 ≤ b,d ≤ M)
 

출력


각 질문에 대한 답을 출력한다.

 

예제 입력

5 5 3
 1 -2 3 2 8
-8 -9 3 4 5
 2 4 7 8 2
 1 4 3 1 4
-1 2 5 -6 3
1 2 3 4
0 0 1 1
2 0 2 1

예제 출력

37
-18
6





문제풀이

https://github.com/JK921/icandoit/blob/develop/multicampus/src/Solution02.java


'스터디 > 알고리즘 문제풀이' 카테고리의 다른 글

[이러닝] 카드놀이  (0) 2019.01.20
[이러닝] 구슬게임  (0) 2019.01.20
[이러닝] 숫자만들기  (1) 2019.01.20
[백준 2157][DP] 여행  (0) 2018.12.04
[백준 12015] 가장 긴 증가하는 부분 수열 2  (0) 2018.12.03

+ Recent posts