函数式组件应用场景
函数式组件是无状态(无响应式数据), 无实例(this)的, 所以函数式组件的一切都是外部传递进来的, 可以通过context来获取, 因此函数式组件可以在这几个场景下应用:
- 在将children, props, data传递给子组件之前操作他们
- 程序化的在多个组件中选择一个来代为渲染(应用:
router-view组件)
比如说,有这样一个应用场景: 我们的搜索的时候, 需要把搜索结果中的关键字加粗, 着亮色, 这时候就可以用到函数式组件 直接操作context.children.
export default {
functional: true,
props: {
keyword: String,
tag: {
type: String,
default: 'div',
},
},
render: function(createElement, context) {
// 着色
function emWord(word) {
let keyword = context.props.keyword;
let vNodes = [];
if (word.indexOf(keyword) > -1) {
let words = word.split(keyword);
for (let i = 0; i < words.length - 1; i++) {
let cur = words[i];
words.splice(i, 1, cur, keyword);
i++;
}
words.forEach(item => {
let vNode = null;
if (item === keyword) {
vNode = createElement('span', { style: { color: 'red' } }, keyword);
} else {
vNode = createElement('span', item);
}
vNodes.push(vNode);
});
} else {
vNodes.push(createElement('span', word));
}
return vNodes;
}
function repalceWordByEm(vNodes) {
for (let i = 0; i < vNodes.length; i++) {
let curVnode = vNodes[i];
// 有子节点
if (curVnode.children && curVnode.children.length) {
repalceWordByEm(curVnode.children);
}
// text节点
else if (!curVnode.tag && curVnode.text !== undefined) {
// 用着色后的节点替换改节点
vNodes[i] = createElement('span', emWord(curVnode.text));
}
}
}
repalceWordByEm(context.children);
return createElement(context.props.tag, context.children);
},
};