Component(컴포넌트)란 프로그램에서 독립적인 프로세스나 기능을 수행하는 Module(모듈)입니다.
Vue 컴포넌트의 파일 확장자는 ".vue"입니다.
Vue 컴포넌트는 <template>, <script>, <style>로 구분되어 있습니다.
<template>
<h1>Hello, Vue!</h1>
</template>
<script>
export default {
name: 'TestComponent'
}
</script>
<style>
h1 {
color: #42b983;
}
</style>
<template>는 Vue 컴포넌트에서 사용할 HTML입니다.
<script>는 Vue 컴포넌트에서 처리할 javascript입니다.
<style>은 <template>에 있는 태그(tag - element)에 대한 css입니다.
Vue 컴포넌트의 <template>, <script>, <style>은 src 속성을 이용하여 외부 파일로부터 가져올 수 있습니다.
<template src="./template.html">
</template>
<script src="./script.js">
</script>
<style src="./style.css">
</style>
<template>는 반드시 있어야 합니다.
<script>와 <style>에 내용이 없으면 삭제해도 됩니다.
<template>에는 반드시 하나 이상의 HTML 태그가 있어야 합니다.
<template>에 HTML 태그가 없다면 "The template requires child element (vue/valid-template-root) - template에 자식 요소가 필요합니다."라는 에러가 발생합니다.
error: The template requires child element (vue/valid-template-root) at src\components\TestComponent.vue:1:1:
> 1 | <template>
| ^
2 | </template>
3 |
4 | <script>
<script>는 일반 javascript를 사용할 수 있습니다.
<script>
var index = 0;
for (index = 0; index < 10; index++) {
console.log(index);
}
alert(index); // 테스트를 위해 사용하였습니다.
</script>
<script>에서 변수 선언할 때 반드시 var, let, const를 사용해야 합니다.
var은 <script> 안에서 변수로 선언합니다.
let은 <script> 안에서 변수로 한 번만 선언되어야 합니다.
const는 <script> 안에서 변수로 한 번만 선언되고 값은 변경할 수 없습니다.
var, let, const를 사용하지 않으면 "is not defined (no-undef) - 정의되지 않았습니다."라는 에러가 발생합니다.
error: 'message' is not defined (no-undef) at src\components\TestComponent.vue:6:1:
4 |
5 | <script>
> 6 | message = 'Hello Vue!';
| ^
7 | </script>
그리고 선언된 변수 Vue 컴포넌트에서 사용하지 않으면 "is assigned a value but never used (no-unused-vars) - 할당되었지만 사용되지 않았습니다."라는 에러가 발생합니다.
error: 'message' is assigned a value but never used (no-unused-vars) at src\components\TestComponent.vue:6:5:
4 |
5 | <script>
> 6 | var message = 'Hello Vue!';
| ^
7 | </script>
const 변수에 값을 변경하면 "is constant (no-const-assign) - 상수입니다."라는 에러가 발생합니다. cost 변수는 값을 변경할 수 없습니다.
error: 'message' is constant (no-const-assign) at src\components\TestComponent.vue:7:1:
5 | <script>
6 | const message = 'Hello Vue!';
> 7 | message = 'Hello Vue!!';
| ^
8 | console.log(message);
9 | </script>
10 |
<script>에서 모든 변수는 동일한 이름으로 재선언 할 수 없습니다.
var 변수를 재선언하면 "is already defined (no-redeclare) - 이미 정의되었습니다."라는 에러가 발생합니다.
error: 'message' is already defined (no-redeclare) at src\components\TestComponent.vue:7:5:
5 | <script>
6 | var message = 'Hello Vue!';
> 7 | var message = 'Hello Vue!!';
| ^
8 | console.log(message);
9 | </script>
let, const 변수를 재선언하면 "Identifier has already been declared - 식별자가 이미 선언되었습니다."라는 파싱 에러(Parsing error)가 발생합니다.
error: Parsing error: Identifier 'message' has already been declared. at src\components\TestComponent.vue:7:4:
1 |
2 | let message = 'Hello Vue!';
> 3 | let message = 'Hello Vue!!';
| ^
4 | console.log(message);
error: Parsing error: Identifier 'message' has already been declared. at src\components\TestComponent.vue:7:6:
1 |
2 | const message = 'Hello Vue!';
> 3 | const message = 'Hello Vue!!';
| ^
4 | console.log(message);
<script>에서는 import를 이용해 모듈(라이브러리)이나 컴포넌트를 가져올 수 있고 export를 이용해 컴포넌트에서 데이터를 처리하거나 상위 Vue 컴포넌트로부터 데이터를 전달받을 수 있습니다.
import로 모듈(라이브러리)이나 Vue 컴포넌트를 가져와 사용할 수 있습니다.
<script>
import axios from 'axios' // 모듈(라이브러리)
import TestComponent2 from './TestComponent2.vue' // Vue 컴포넌트
</script>
가져온 Vue 컴포넌트의 이름은 Vue 컴포넌트의 <script>의 export에 있는 name을 사용하지 않아도 됩니다. 그리고 가져온 Vue 컴포넌트의 이름은 중복되지 않아야 합니다.
export default는 반드시 하나만 있어야 합니다.
export default가 두 개 이상이면 "Only one default export allowed per module. - 모듈당 하나의 기본 내보내기만 허용됩니다."라는 파싱 에러(Parsing error)가 발생합니다.
error: Parsing error: Only one default export allowed per module. at src\components\TestComponent.vue:
3 | name : 'TestComponent'
4 | }
> 5 | export default {
| ^
6 | name : 'TestComponent1'
7 | }
export의 속성은 다음과 같습니다.
name
name은 Vue 컴포넌트의 이름입니다. (필수는 아닙니다.)
<script>
export default {
name : 'TestComponent'
}
</script>
components
components는 import로 가져온 Vue 컴포넌트를 사용하기 위해 import 한 이름으로 등록합니다.
그리고 등록된 Vue 컴포넌트는 <template>에서 태그로 사용되어야 합니다.
<template>
<h1>Hello, Vue!</h1>
<TestComponent2 />
</template>
<script>
import TestComponent2 from './TestComponent2.vue'
export default {
name : 'TestComponent',
components : {
TestComponent2
}
}
</script>
<style>
h1 {
color: #42b983;
}
</style>
TestComponent2.vue
<template>
<h2>Have a good time</h2>
</template>
<script>
export default {
name : 'TestComponent2'
}
</script>
<style>
</style>
import로 가져온 TestComponent2 컴포넌트를 components에 등록하고 <template>에서 <TestComponent2>로 사용합니다.
components에서 가져온 Vue 컴포넌트를 components에 등록하지 않으면 "is defined but never used (no-unused-vars) - 정의되었지만 사용되지 않았습니다."라는 에러가 발생합니다.
error: 'TestComponent2' is defined but never used (no-unused-vars) at src\components\TestComponent.vue:6:8:
4 |
5 | <script>
> 6 | import TestComponent2 from './TestComponent2.vue'
| ^
7 |
8 | export default {
9 | name : 'TestComponent'
components에 등록된 Vue 컴포넌트를 <template>에서 사용하지 않으면 "component has been registered but not used - 컴포넌트가 등록되었지만 사용되지 않았습니다."라는 에러가 발생합니다.
error: The "TestComponent2" component has been registered but not used (vue/no-unused-components) at src\components\TestComponent.vue:11:3:
9 | name : 'TestComponent',
10 | components : {
> 11 | TestComponent2
| ^
12 | }
13 | }
14 | </script>
가져온 Vue 컴포넌트에 데이터를 전달하기 위해서는 가져온 Vue 컴포넌트의 export props에 정의된 속성 명과 타입으로 설정해야 합니다.
<TestComponent2 userId="testid" />
props
props는 상위 Vue 컴포넌트로부터 데이터를 전달받기 위해 속성 명과 타입을 설정합니다.
데이터 타입은 네이티브 생성자(String, Number, Boolean, Function, Object, Array, Symbol) 중 하나를 사용할 수 있습니다.
속성 명으로 전달받은 데이터는 <template>에서 바인딩하여 사용됩니다. 데이터 바인딩은 이중 중괄호(일명 Mustache - 머스태시 - 수염)로 처리됩니다. 이중 중괄호는 HTML이 아닌 일반 텍스트로 데이터를 처리합니다.
<template>
<h1>Hello, Vue!</h1>
<h3>{{userId}}님, 안녕하세요.</h3>
</template>
<script>
export default {
name : 'TestComponent',
props : {
userId : String
}
}
</script>
<style>
h1 {
color: #42b983;
}
</style>
상위 Vue 컴포넌트로부터 "userId"으로 전달받은 데이터를 <template>에서 이중 중괄호 구문(일명 Mustache - 머스태쉬 - 수염)을 이용하여 바인딩합니다.
전달받은 데이터는 <template>에서 사용하지 않아도 문제는 없습니다. 그리고 상위 Vue 컴포넌트로부터 전달받지 못한 속성들은 <template>에서 빈 공간으로 처리됩니다.
App.vue에서 import로 TestComponent.vue를 가져와 사용합니다.
<template>
<img alt="Vue logo" src="./assets/logo.png">
<TestComponent userId="testid" />
</template>
<script>
import TestComponent from './components/TestComponent.vue'
export default {
name: 'App',
components: {
TestComponent
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
porps에 여러 개의 속성 명을 설정하여 사용할 수 있습니다.
<template>
<h1>Hello, Vue!</h1>
<h3>{{userId}}({{userNo}})님, 안녕하세요.</h3>
</template>
<script>
export default {
name : 'TestComponent',
props : {
userId : String,
userNo : Number
}
}
</script>
<style>
h1 {
color: #42b983;
}
</style>
그리고 변수의 타입(type), 필수 여부(required), 기본값(default)을 설정할 수 있습니다.
props : {
userId : {
type : String,
required : true
},
userNo : {
type : Number,
required : false,
default : 0
}
}
이어서 export의 data, methods, event, watch, computed, lifecycle에 대해 설명하겠습니다.
참고로
Vue 컴포넌트에서 비정상적인 문자가 공백이 포함되어 있다면 "Irregular whitespace not allowed (no-irregular-whitespace) - 불규칙한 공백은 허용되지 않습니다."라는 에러가 발생합니다.
3번째 줄 앞에 눈에 보이지 않지만 깨진 문자가 포함되어 있었습니다.
Vue 컴포넌트의 주석문은 <template>, <script>, <style>에 맞게 사용해야 합니다.
<template>
<!-- 컴포넌트에서 사용할 HTML 입니다. -->
</template>
<script>
// 컴포넌트에서 처리할 javascript 입니다.
</script>
<style>
/* template에 있는 element에 대한 css 입니다. */
</style>
Vue 프로젝트나 컴포넌트를 만들고 실행하기(npm run serve) 전에 오류 체크를 위해 npm run lint 명령어를 실행하기기 바랍니다.
npm run lint
그럼 위의 내용처럼 정확하게 오류를 찾아 수정할 수 있습니다.