web技术支持| 简单实现Vue第一章:模板编译


创建vue构造函数

function Vue(option) {
    this.$option = option;
}

挂载方法

Vue.prototype.$mount = function(element) {
    const rootNode = document.getElementById(element);
    if (rootNode) {
        this.$rootNode = rootNode;
    } else {
        throw new Error('$mount Receives an ID node');
    }

    if (this.$option.template) {
        this.$render();
    } else {
        throw new Error('The lack of the template');
    }

    return this;
}


Vue.prototype.$render = function render() {
    this.$AST = this.$templateCompilation(this.$option.template);
}


Vue.prototype.$templateCompilation = function templateCompilation(html) {
    const AST = {
        attrs: [],
        children: []
    };

    function start(AST) {
        let result = html.match(startReg.startTag);
        AST.tagName = result[0];
        cuttingHTML(result);

        while (html.match(startReg.endTag).index) {
            result = html.match(startReg.startAttrs);
            AST.attrs.push({
                key: result[0].split('=')[0],
                value: result[1]
            });
            cuttingHTML(result);
        }
        
        cuttingHTML(html.match(startReg.endTag));
        text(AST);
        return AST;
    }
    

    function text(parent) {
        while (html && html.match(textReg.endTag).index) {
            let result = html.match(textReg.startTag);
            if (result && !result.index) {
                parent.children.push(start(JSON.parse(JSON.stringify(AST))));
            } else {
                result = html.match(textReg.text);
                parent.children.push(result[0]);
                cuttingHTML(result);
            }
        }
        
        cuttingHTML(html.match(textReg.endTag));
    }
    
    function cuttingHTML(result) {
        html = html.substr(result.index + result[0].length);
    }

    return start(JSON.parse(JSON.stringify(AST)));
}

创建reg.js

const startReg = {
    startTag: /[\w\d]+/,
    startAttrs: /[^\s=]+\s*=\s*('[^'>]*'|"[^">]*")/,
    endTag: /\s*>/
};


const textReg = {
    startTag: /\s*<[\w\d]+/,
    text: /[^<]+/,
    endTag: /\s*<\/[a-z0-9]+>/i
};

使用




    
    
    
    Document
    
    

    


    

效果截图

注意:上述代码无法实现以下效果,本章代码只进行了模板编译,还没有渲染真实DOM;

image.png

在这里插入图片描述