Vue.js 3 & NodeJS/Vue 3

Vue CLI 컴포넌트 이해 1 - Vue CLI Components export(name, components, props)

carrotweb 2021. 8. 8. 20:00
728x90
반응형

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

그럼 위의 내용처럼 정확하게 오류를 찾아 수정할 수 있습니다.

728x90
반응형