用了这么久Vue,你想自己实现它吗?

112 阅读2分钟

今天有什么好玩的咩?

有,那就是模仿 Vue 做个模板引擎 😆

话不多说,我们直接上代码

    const vm = new Vue({
        el: '#root',
        data: {
            username: 'zs',
            age: 13,
            greeting: {
                method1: '你好鸭',
                method2: 'Hello'
            }
        }
    })
console.log("vm 实例对象", vm)

在上面我们假装自己有一个类似 Vue 的加工函数,因此我们就可以直接调用使用它啦~

我们像使用 Vue 一样,把它基本的需要的参数传进去,比如你要知道对哪个模板进行解析吧?比如你预定义要填充的数据是什么吧?这两个是最起码的,所以,接下来就是对这个 Vue 函数的 implementation 实现部分做具体构造了。

下面是具体的实现代码:

    function Vue (options) {
        this.el = options?.el;  // 获取模板选择器
        this.data = options?.data;  // 准备数据

        let root = document.querySelector(this.el);// 获取模板节点
        let templates = root.innerText; // 得到节点内容
        const pattern = /{{\s*([a-zA-Z_$][a-zA-Z0-9_$]+)\s*}}/;
        let result; // 匹配的正则对象结果
        // 循环遍历将插值语法进行替换为变量对应的值
        while (result = pattern.exec(templates)) {
            templates = templates.replace(result[0], this.data[result[1]]);
        }
        root.firstChild.data = templates;    // 将替插值语法的变量替换为真实数据后,放回页面模板中
        return this;
    }

这里首先是 el 参数,它是获取页面 DOM 的 CSS 选择器,这里假设我们不做更细致的划分,那我们就直接使用通配的 querySelector 方法来获取元素吧。

关键的部分是在提取类似 Vue 中插值语法的那些变量,并将它替换为我们准备好的数据。

要完成上面这一步,我们需要定义正则提取的规则,之后获得正则匹配对象结果,然后对匹配结果中的双括号内容 {{ var_name }}var_name 变量结合模板内容进行替换操作。等循环走完,也就替换完成,最后将数据替换后的模板再重新放回页面对应的节点即可。

至此,我们就完成了 Vue 实现的一小步,哈哈哈 😂 ...