• v-for的简单实现


    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title></title>
    <style type="text/css">
        li{
            height:30px;
            line-height:30px
        }
        li:not([data-key]){
            color:red;
            font-size:16px
        }
    </style>
    </head>
    <body>
        <div id="example-1">
            <div>这是一个v-for的示范</div>
            <div>
                <ul>
                    <li>第一个v-for</li>
                    <li v-for="(item,index) in list" :key="id">
                      {{ item.message }}
                    </li>
                    <li>第二个v-for</li>
                    <li v-for="(student,no) in students" :key="no">
                      {{ student.name }}
                    </li>
                    <li>下面是数组v-for</li>
                    <li v-for="(n,m) in arr" :key="m">
                      {{ n }}
                    </li>
                </ul>
            </div>
        </div>
    </body>
    </html>
    <script>
        class Vue{
            constructor(obj){
                this.mountEl = document.querySelector(obj.el);
                this.data = obj.data;
                this.hasChild(this.mountEl);
            }
            hasChild(el){
                if(el.children){
               //        类数组转为数组四种方法
                    //        Array.prototype.call(arr)
                    //        [].slice.call(arr)
                    //        Array.from(arr)
                    //        [...arr].forEach(item=>{
                    //            console.log(item)
                    //        })
                       let nodeList = mountEl.children;
                    [...el.children].forEach(el=>{
                    //在这里处理v-for
                        let vF_val = el.getAttribute('v-for');
                        if(vF_val){
                          //v-for的dataList
                              let todoList = null;
                          // key绑定的名称  id
                              let keyName = el.getAttribute('v-bind:key') || el.getAttribute(':key');
                          //li标签内部的大胡子括号中的 item.message
                              let textName = el.innerText.replace('{{','').replace('}}','').trim();
                            let regex="\((.+?)\)";
                          //匹配小括号中的内容,不包括小括号 ,结果为item,index
                              let item_index = vF_val.match(regex)[1];//item,index
                              let item = item_index.split(',')[0]// item
                              let index = item_index.split(',')[1]// index
                              let num = vF_val.lastIndexOf('in');
                            let datListName = vF_val.substr(num+2).trim();//list
                               for(let i in this.data){
                              if(i == datListName){
                                  todoList = this.data[i]
                              }
                            }
                            const fragment = document.createDocumentFragment();
                           for(let i = 0;i<todoList.length;i++){
                              let tab = null;
                              if(todoList[i] instanceof Array){
                                  tab = false
                              }else if(todoList[i] instanceof Object){
                                  tab = true
                              }
                              let todoItem = todoList[i]
                              let li = document.createElement(el.tagName)
                              if(!tab){
                                  li.dataset.key = i;
                                  li.innerText = todoItem;
                                  fragment.appendChild(li);
                              }else{
                                  li.dataset.key = todoItem[keyName]
                                  if(textName.split('.')[0] === item){// v-for的item和item.message相同变量名
                                           let k = textName.split('.')[1] //message
                                           li.innerText = todoItem[k];
                                      fragment.appendChild(li);
                                  }
                              }
                          }
                          el.parentNode.replaceChild(fragment,el)
                        }
                        if(el.children){//递归查询元素
                            this.hasChild(el)
                        }
                    })
                }
            }
        }
        var example1 = new Vue({
          el: '#example-1',
          data:{
              msg:1,
            list: [
              { message: 'Foo' ,id:'0'},
              { message: 'Bar' ,id:'1'},
              { message: 'Ace' ,id:'2'},
              { message: 'Mvp' ,id:'3'},
            ],
            students: [
              { name: '李雷雷' ,no:'0'},
              { name: '韩梅梅' ,no:'1'},
              { name: 'poly' ,no:'2'},
            ],
            arr:[11111,222222,333333]
          }
        })
    </script>

    运行结果如下:

    总结:真正的vue是会处理得到虚拟dom再去render生成dom的,并且实例中维护的数据都是具有setter,getter属性以及watch监察者的,以此达到响应式,这里只是简单的模拟实现一下。

  • 相关阅读:
    hbase二级索引学习
    redis-cluster集群Mac部署
    http-flume-kafka.conf
    linux 替换文件中的字符串
    flumeDemo
    redis_exporter监控安装
    Hbase内存磁盘大致关系
    spring cloud 尚硅谷学习
    C10K问题
    navicat 远程链接Mysql问题
  • 原文地址:https://www.cnblogs.com/hjj2ldq/p/9530862.html
Copyright © 2020-2023  润新知