함수형 컴포넌트

어떠한 상태도 없고 라이프사이클 관련 메소드도 사용하지 않을때 지금까지 사용해왔었던 컴포넌트 생성 방법을 사용한다면 사용하지도 않는 메소드를 추가하게 됩니다. 함수형 컴포넌트를 사용하면 심플하게 작성할수 있습니다.

사용방법

functional 속성으로 사용

functional 속성을 사용하는 경우 template 태그를 사용할수 없습니다. 이때 render 함수를 사용 합니다.

1
2
3
4
5
6
7
8
<script>
export default {
functional : true,
render(h, context) {
// ...
}
}
</script>

장점

함수형 컴포넌트는 라이프 사이클 메소드를 가지지 않습니다. 이를 통해서 앱 퍼포먼스 향상 효과를 가질수 있습니다.

FunctionalView
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<template>
<div>
<template v-for="item in list">
<functional-component :key="item"/>
</template>
</div>
</template>

<script>
import FunctionalComponent from '../components/functional/FunctionalComponent.vue';

export default {
components: {
FunctionalComponent
},
data() {
return {
list: []
}
},
created() {
for (let i = 0; i < 1000; i++) {
this.list.push(i);
}
}
}
</script>

<style scoped>

</style>
FunctionalComponent
1
2
3
4
5
6
7
8
9
10
11
12
<script>
export default {
functional: true,
render(h) {
return h('div', '함수형 컴포넌트');
}
}
</script>

<style scoped>

</style>

함수형 컴포넌트를 1000개 생성하고 있습니다. 하지만 count는 1이라는 것을 확인할수 있습니다.

NoneFunctionalComponent

functional만 지우고 나머지는 위의 코드와 동일 합니다.

1
2
3
4
5
6
7
8
9
10
11
<script>
export default {
render(h) {
return h('div', '함수형 컴포넌트');
}
}
</script>

<style scoped>

</style>


SPA에서 functional 사용하기

2.5.0+ 이후로는 템플릿 기반의 함수형 컴포넌트를 정의할수 있습니다. template 태그에 functional 속성을 추가하면 동일하게 함수형 컴포넌트를 사용할수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
<template functional>
<div>함수형입니다.</div>
</template>
<script>
export default {
}
</script>

<style scoped>

</style>

Comment and share

Render 함수를 이용한 컴포넌트 작성

template을 사용하지 않고 render함수를 이용하여 컴포넌트를 작성 할수 있습니다. 이때 createElement 함수를 사용하여 작성합니다.

기본 구성

컴포넌트 작성시의 차이점은 template 속성을 사용 하는 대신에 render 함수를 사용한다는 차이점 뿐입니다. render함수는 return으로 VNode를 반환해주기만 하면 됩니다. VNode 생성은 createElement함수를 호출하면 반환해 줍니다(this.$createElement로도 동일하게 사용 가능).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
export default {
name: '',
proprs: {},
created() {

},
data() {
return {}
},

// h를 쓰기도 하고 createElement라고 쓰기도 한다.
render(h) {
return h('div', ['값']);
}
}
createElement 함수 호출
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
createElement(
// {String | Object | Function}
// HTML 태그 이름(사용자가 만든 컴포넌트 태그 이름 포함), 컴포넌트 옵션 또는 함수 중
// 하나를 반환하는 함수. 필수사항
'div',

// {Object}
// 컴포넌트에서 사용할 속성 값을 설정합니다.
// 해당 값은 선택사항 입니다.
{

},

// {String | Array}
// VNode 자식들
// 하위 태그를 작성할때 사용 합니다.
// createElement()를 사용하거나, 문자열을 입력 가능합니다.
// 해당 값은 선택사항 입니다.
[
'문자열',
createElement('h1', '옵션 사용 없이 바로 문자열')
]
)
1
2
3
4
5
6
7
8
9
createElement(
'div',
{
props
},
[
'문자열'
]
)

지금까지 확인결과 VNode 자식값을 사용할시에 배열로 넘기자.

데이터 객체

createElement의 두번째 파라미터로 사용 하는 데이터 객체는 컴포넌트에 속성을 정의 할때 사용하게 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
// v-bind:class와 동일
'class': {
foo: true,
bar: false
},

// v-bind:style와 동일
style: {
color: 'red'
},

// 일반 HTML 속성을 정의할때 사용
attrs: {
id: 'foo'
},

// DOM 속성을 정의할때 사용
domProps: {
innerHTML: 'baz'
},

// v-on:click 등과 같은 역할을 합니다.
on: {
click: this.handlerClcik
},

// 다른 컴포넌트의 slot으로 들어가는 컴포넌트인 경우 슬롯의 이름을 여기에 적어줍니다.
slot: 'slot-name',

// ref를 지정하고 싶으면 해당 key를 사용합니다.
ref: 'refValue'
}

Comment and share

Vue 컴포넌트 작성

Vue에서는 템플릿을 통해서 HTML을 작성하는 것을 권장하고 있습니다. 하지만 특정 상황에서는 자바스크립트를 이용해야 하는 상황이 있습니다. 그렇기 때문에 템플릿 뿐 아니라 자바스크립트로도 컴포넌트를 작성하는 방법에 대해서 알고 있어야 합니다.

싱글 파일 컴포넌트

template, script, style 3개의 태그를 이용하여 하나의 파일에서 작성 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<template>
<div>
{{ str }}
</div>
</template>

<script>
export default {
name: 'VueSingleFileComponent',
props: {
str: {
type: String
}
}
}
</script>

<style scoped>

</style>
사용하기

다른 컴포넌트에서 import를 통해 사용할수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
<vue-string-file-component/>
</template>

<script>
import VueSingleFileComponent from './VueSingleFileComponent.vue';

export default {
name: 'VueView',
components: {
VueSingleFileComponent
}
}
</script>

<style>
</style>

Vue.component를 통해서 등록하면 실제 사용하는 곳에서 import를 할 필요 없이 사용할수 있습니다.

main.js
1
2
3
4
import Vue from 'vue';
import VueSingleFileComponent from './VueSingleFileComponent.vue';

Vue.component('vue-single-file-component', VueSingleFileComponent);
VueView.vue

컴포넌트를 import 하거나 components 속성을 등록 할 필요 없이 사용가능합니다.

1
2
3
4
5
6
7
8
9
10
11
12
<template>
<vue-string-file-component/>
</template>

<script>
export default {
name: 'VueView',
}
</script>

<style>
</style>

String으로 컴포넌트 작성

템플릿을 js의 String으로 정의하는 방법입니다. 위 처럼 vue 확장자를 가진 파일을 따로 생성하지 않고 Vue.component에 직접 등록 합니다.

1
2
3
4
5
6
7
8
9
10
import Vue from 'vue';

Vue.component('vue-string', {
template: '<div> {{ str }}</div>',
props: {
str: {
type: String
}
}
})

Vue.component를 사용하기 때문에 import로 호출만 하고 compoents 속성에 따로 등록 하진 않아도 됩니다.

1
2
3
4
5
6
7
8
<template>
<vue-string/>
</template>
import '../components/vue-render/VueString.js';

export default {
name: 'VueView',
}

Render function을 사용하여 컴포넌트 작성

template을 사용하지 않고 render 함수를 이용해서 컴포넌트를 작성 할수 있습니다. 해당 컴포넌트를 import해서 사용방법은 SPA랑 동일 합니다.

1
2
3
4
5
6
7
8
9
10
11
export default {
name: "VueRenderFunc",
props: {
str : {
type: String
}
},
render(h) {
return h('div', [this.str]);
}
}

결론

기본적으로 SPA 방식으로 작성하는 게 좋다고 생각합니다. js를 활용해야 하는 경우에는 render 함수를 이용하여 작성하는 것도 하나의 선택이 될수 있을거라 생각합니다.

Comment and share

  • page 1 of 1

Moon Star

author.bio


author.job