vue初步学习-数据驱动-01

63 阅读1分钟
            ## 数据驱动

vue执行流程

1、获得模板 模板中有坑 {{}}就是先获取到这样的一个模板

<div class="root" id="root">
        <div>
            <p>{{name}} {{message}}</p>
        </div>
        <p>{{name}}</p>
        <p>{{message}}</p>
    </div>

2、利用vue构造函数中的数据来进行填坑,得到可以再页面中显示的标签

vue其实就是利用我们提供的数据和页面中的模板生成了一个新的html标签,替换到页面中放置模板的的位置

现在先简单的对这个填坑的操作进行一个模拟

1、首先先写一个模板就像vue那样的标签结构

<div class="root" id="root">
        <div>
            <p>{{name}} {{message}}</p>
        </div>
        <p>{{name}}</p>
        <p>{{message}}</p>
    </div>

2、获取到标签结构

 let template = document.querySelector('#root')

3、定义变量data

   let data = {
        name: "一个新name",
        message: "一个消息"
    }

4、使用递归对标签进行处理

//花括号的正则
  var kuohao = /{{(.+?)}}/g
function compiler(template, data) {
        let childrenNodes = template.childNodes; //取出子元素
        console.log(childrenNodes)
        for (var i = 0; i < childrenNodes.length; i++) {
            let type = childrenNodes[i].nodeType; //1、 文本   3、文本节点
            if (type === 3) {
                //文本节点可以判断是否有{{}}插值
                let txt = childrenNodes[i].nodeValue; //该属性只有文本节点才有意义
                //判断有没有双括号
                let txt2 = txt.replace(kuohao, function (_, g) {
                    //replace使用正则匹配一次就会被调用一次函数
                    let key = g.trim()//写在花括号里面的东西
                    // console.log('g', g)
                    let value = data[key]
                    //将{{xxx}}用这个进行替换
                    //txt与dom没有关系的
​
                    return value
                })
​
                childrenNodes[i].nodeValue = txt2
            } else if (type === 1) {
                //元素,考虑是否有子元素,是否需要将其进行递归处理,判断是否要插值
                compiler(childrenNodes[i], data)
            }
        }
    }
​

整体代码

<!DOCTYPE html>
<html lang="en"><head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head><body>
    <div class="root" id="root">
        <div>
            <p>{{name}} {{message}}</p>
        </div>
        <p>{{name}}</p>
        <p>{{message}}</p>
    </div>
</body>
<script>
    var kuohao = /{{(.+?)}}/g
    //步骤  
    //1、拿到模板
    //2、拿到数据
    //3、将数据与模板结合,得到的是html元素
    //4、放与页面中
    //拿到模板
    let template = document.querySelector('#root')
    let data = {
        name: "一个新name",
        message: "一个消息"
    }
    //使用递归
    //当前案例中的template是dom元素 ,在vue源码中是dom->字符串模板->vNode => dom
​
    function compiler(template, data) {
        let childrenNodes = template.childNodes; //取出子元素
        console.log(childrenNodes)
        for (var i = 0; i < childrenNodes.length; i++) {
            let type = childrenNodes[i].nodeType; //1、 文本   3、文本节点
            if (type === 3) {
                //文本节点可以判断是否有{{}}插值
                let txt = childrenNodes[i].nodeValue; //该属性只有文本节点才有意义
                //判断有没有双括号
                let txt2 = txt.replace(kuohao, function (_, g) {
                    //replace使用正则匹配一次就会被调用一次函数
                    //函数第0个参数表示匹配到的内用 
                    //函数的第n个参数 表示u正则中的第n组
                    let key = g.trim()//写在花括号里面的东西
                    // console.log('g', g)
                    let value = data[key]
                    //将{{xxx}}用这个进行替换
                    //txt与dom没有关系的
​
                    return value
                })
​
                childrenNodes[i].nodeValue = txt2
            } else if (type === 1) {
                //元素,考虑是否有子元素,是否需要将其进行递归处理,判断是否要插值
                compiler(childrenNodes[i], data)
            }
        }
    }
    let genereateNode = template.cloneNode(true)
    console.log(template)
    compiler(genereateNode, data)
    console.log(genereateNode)
    //没有生成新的template 所以这里是直接在页面中更新数据的,因为dom是引用类
    //放于页面中
    root.parentNode.replaceChild(genereateNode, root)
​
    /*
    上面的思路有很大的问题
    1、vue使用的是虚拟dom
    2、只考虑了单属性 {{name}} , 而vue中 使用层级是 {{children.name}}
    3、代码没有整合
    
    */
</script></html>

\