Tại sao viết Function Component?
Khi viết function component, chúng ta phải tự xử rất nhiều thứ (bên dưới sẽ có liệt kê), vậy câu tại sao chúng ta lại muốn dùng đến nó?
Anh Austin Gil ảnh có đo, thì thấy function component nó nhanh hơn so với một component có state.
Function Component trong Vue là gì?
Component không chứa state
và không có instance
, không thể truy xuất bằng từ khóa this
// dùng vue template
<template functional>
<div>...</div>
</template>
// dùng render function
<script>
export default {
functional: true,
render(h) {
//...
}
}
</script>
Truy xuất dữ liệu
Nếu không có state
hay instance
vậy làm sao chúng ta có thể tham chiếu đến dữ liệu và phương thức?
Vue cung cấp tham số context
bên dưới hàm render để chúng ta truy xuất: prop, children, slot, scopedSlot, data, parent, listener, injection
<template functional>
<div>
{{ props.someProp }}
</div>
</template>
<script>
export default {
props: {
someProp: String
}
}
</script>
<script>
export default {
functional: true,
props: {
someProp: String
},
render(h, ctx) {
const someProp = ctx.props.someProp
}
}
</script>
Attribute
attribute không được truyền xuống tự động, ví dụ như class
và id
mặc định bị bỏ qua
<!-- src/components/ArticleTeaser.vue -->
<template>
<UiHeadline
id="hyphenCase(article.title)"
class="ArticleTeaser__title"
@click="readMore"
>
{{ article.title }}
</UiHeadline>
</template>
<!-- src/components/UiHeadline.vue -->
<template functional>
<h1>
<slot />
</h1>
</template>
id
, class
, kể cả @click
cũng không được truyền xuống. Nếu không mở source code đó ai mà biết được tại sao truyền các attribute này xuống mà nó không chạy.
Hên là có cách giải quyết, nếu bạn đã viết function component thì bạn phải chịu trách nhiệm bổ sung cách giải quyết cho nó
<template functional>
<h1
v-bind="data.attrs"
v-on="listeners"
>
<slot />
</h1>
</template>
Tuy nhiên, chưa xong hết được, vì class
nó lại không nằm trong data.attrs
Bạn phải thông qua data.class
/ data.staticClass
và data.style
/data.staticStyle
<!-- Đưa vào `data.class` -->
<UiHeadline :class="['my-class']"/>
<!-- Đưa vào `data.staticClass` -->
<UiHeadline class="my-class"/>
<template functional>
<h1
:class="[data.class, data.staticClass]"
:style="[data.style, data.staticStyle]"
v-bind="data.attrs"
v-on="listeners"
>
<slot />
</h1>
</template>
Initializing...