MVVM,MVC,VUE的基本实现原理

什么是mvvm?

m:model 数据层;

v:view 视图层;

vm:viewModel 视图层跟数据层的连接桥梁

解释:m是后端传过来的数据,v是前端渲染后端数据所看见的页面;

vm通过数据绑定来实现数据->视图,视图->数据,vm通过Dom事件监听数据跟视图的变化来实现数据跟视图的更新;

当监听到数据变化的时候,视图层自动更新,当用户操 作视图层的时候,vm监听到视图的变化通知数据更新.实际上就实现了数据的双向绑定.

除此之外,vm层还能跟v层进行相互通信.

如上图所示;

我们可以模拟一下mvvm的基本实现:

html:

<input type="text" id="input1"/>
<span id="span1"></span>

js:

var m={a:''};
var v={};
var vm={
  init(){
    input1.onkeyup=function(){
      m.a=this.value;
      vm.observer(m,"a"); 
    }
  },
  observer(obj,attr){
    var val=obj[attr];
    Object.defineProperty(obj,attr,{
        get(){
          return val;
        },
        set(v){
          input1.value=span1.innerHML=val=v;  
       }
    })
  }

};

vm.init();

什么是mvc?

m:model 数据层(模型)

v:view 视图层

c:controller 控制器

解释:

 M和V指的意思和MVVM中的M和V意思一样。C即Controller指的是页面业务逻辑。使用MVC的目的就是将M和V的代码分离。‘MVC是单向通信。也就是View跟Model,必须通过Controller来承上启下,

将用户界面和业务逻辑合理的组织在一起,起粘合剂的效果。所以Controller中的内容能少则少,这样才能提供最大的灵活性。

如上图所示,我们也可以模拟一下mvc的基本实现;

html:

<input type="text" id="input1"/>
<span id="span1"></span>

js:

var m={
a:'',
Set(val){
m.a=val;
v.render();
},
Get(){
return m.a;
}
};
var v={
init(){
input1.onkeyup=c.Keyup;
},
render(){
span1.innerHTML=m.Get();
}
};
var c={
Keyup(){
m.Set(this.value)
}
}

v.init();

 

vue的基本实现原理

关于Object.defineProperty();

Object.defineProperty()可以在对象中再定义或者修改属性,可以对该属性的读写性,可行性等进行操作;

三个必须参数:

obj(目标对象),attr(属性),desc(描述)

  • obj: 需要进行定义或修改属性的对象;
  • attr: 需要进行定义或者修改的属性;
  • desc: 该属性的描述符(包含存取描述符和数据描述符),该参数以一个对象的形式传入,该参数有六个选项:
    • value: 设定该属性的值;
    • writable: 布尔,该属性是否可写入(是否可改变其value);
    • enumerable: 布尔,该属性是否可被遍历得到(for...in, Object.keys等);
    • configurable: 布尔,设定该属性是否可被删除,且除writable外的其他描述符是否可被修改;
    • get: 函数,该属性的值被获取时执行的回调函数(例如console.log(prop)),默认为undefined;
    • set: 函数,该属性的值被设置时执行的回调函数,默认为undefined;

话不多说,上代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>v-model  | v-text 基本实现</title>
</head>
<body>
    <input type="text" v-model="a"> 
    <span v-text="a"></span> 
    <br>
     {{a}}

     <script>

        //  console.log(Object.defineProperty)
     
       var m={
         a:''
       };
     
       var v={

       };
     
       var vm={
         nodeList:{}, 
         init(){
           var nodes=document.body.childNodes;        
        //    console.log(nodes)
            for(var i=0;i<nodes.length;i++){
                var node=nodes[i];
                vm.compile(node)
            }
            // console.log(vm.nodeList)
        //    vm.observer()

         }, 
         compile(node){
             var name="";
            //  console.log(node+" --"+node.attributes)
            //    console.log(node+":  "+node.nodeType) 
            if(node.nodeType===1){
                //元素节点
                var attrs=node.attributes;  
                for(var i=0;i<attrs.length;i++){
                    //   console.log(attrs[i])
                    var nodeName=attrs[i].nodeName; 
                    var nodeValue=attrs[i].nodeValue;
                    // console.log(nodeName,nodeValue)
                   if(nodeName==='v-model'){
                        name=nodeValue;
                       node.addEventListener('keyup',function(){
                           m[name]=this.value;
                       })
                      vm.observer(m,name);
                   }
                   if(nodeName==='v-text'){
                        name=nodeValue; 
                   }  

                }
            }; 
            if(node.nodeType===3){
                //文本节点
                // console.log(node.nodeValue)
                var arr=node.nodeValue.match(/{{(.+)}}/);
                if(arr){
                    // console.log(arr)
                    name=arr[1];
                } 
            }
            // console.log(name,node)
           if(name){
             if(vm.nodeList[name]==undefined){
                 vm.nodeList[name]=[];
             }
                 vm.nodeList[name].push(node);
           }

         },

         observer(obj,attr){
             var val=obj[attr];   
             Object.defineProperty(obj,attr,{
                 get(){
                    return val;
                 },
                 set(v){
                   val=v;                 
                   var arr=vm.nodeList[attr];
                //    console.log(arr)
                   for(var i=0;i<arr.length;i++){
                        var node=arr[i];
                       if(node.nodeType===1){
                        if(node instanceof HTMLInputElement){
                             node.value=v;
                        }else{
                             node.innerHTML=v;
                        }
                       }
                       if(node.nodeType===3){
                           node.nodeValue=v;
                       }

                   }


                 }

             }) 

         }

       }     

       vm.init();
     
     </script> 



</body>
</html>

猜你喜欢

转载自www.cnblogs.com/xxcnhj/p/11028190.html