Vue 官网对函数式组件有以下描述:
我们可以将组件标记为 functional
,这意味它无状态 (没有响应式数据),也没有实例 (没有 this
上下文)。
一个函数式组件就像这样:
Vue.component('my-component', {
functional: true,
// Props 是可选的
props: {
// ...
},
// 为了弥补缺少的实例
// 提供第二个参数作为上下文
render: function (createElement, context) {
// ...
}
})
组件里面所用的数据是通过render函数中的第二个参数context传递过来的。
下面我们就通过一个例子来看看函数式组件怎么用。需求:用函数式组件渲染出如下结果
最上边是图片,在图片的右下角是个logo图片,在图片下面是两行文字。
还是直接上代码吧,代码中在关键的地方写了注释。
<html>
<head>
<style type="text/css">
</style>
</head>
<body>
<script src="./vue.js"></script>
<div id="app">
<list-view-comp :id="'listViewId'" :list-data="listData"></list-view-comp>
</div>
<script>
Vue.component('listViewComp', {
functional: true, // should be set true for functional component
props: {
listData : {type : Array, required : true}
},
render(createElement, context){
console.log("icon is: " + context.props.listData[0].icon);
console.log("title is: " + context.props.listData[0].title);
var logoDom = createElement(
"div",
{
style : {
width : "68px",
height : "85px",
position: "absolute",
right : "0px",
bottom : "0px",
backgroundImage : `url(${context.props.listData[0].logo})`
}
}
);
var iconDom = createElement(
"div",
{
style : {
width : "450px",
height : "237px",
position: "relative",
backgroundImage : `url(${context.props.listData[0].icon})`
}
},
[logoDom] //iconDom is parent, logoDom is children
);
var titleDom = createElement(
"div",
{
style : {
width : "450px",
height : "30px",
color : "red"
}
},
context.props.listData[0].title
);
var subTitleDom = createElement(
"div",
{
style : {
width : "450px",
height : "30px",
color : "green"
}
},
context.props.listData[0].subTitle // subTitle is passed down by context
);
return createElement(
"div",
{
style : {
width: "1000px",
height: "300px"
}
},
[iconDom, titleDom, subTitleDom] //The div have three children: iconDom, titileDom, subTitleDom
)
}
})
const app = new Vue({
data(){
return{
listData : [
{
icon : "./icon.png",
logo : "./logo.png",
title : "title 1",
subTitle : "sub title 1"
}
]
}
}
}).$mount("#app");
</script>
</body>
</html>
从上面的代码看出函数式组件要在组件中声明functional: true 。
如哪还有不明白的地方请留言探讨。