函数式组件应用场景

1,084 阅读1分钟

函数式组件应用场景

函数式组件是无状态(无响应式数据), 无实例(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);
    },
};