>  기사  >  웹 프론트엔드  >  Vue 소스 코드를 함께 배우고 이해하세요

Vue 소스 코드를 함께 배우고 이해하세요

零下一度
零下一度원래의
2017-06-26 09:50:481407검색

vue 공식 웹사이트에 따르면, vue는 mvvm 프레임워크이고 반응형이라는 것을 알 수 있습니다. 그 의미를 더 깊이 이해하기 위해 간단한 mvvm 학습 데모를 구현했습니다. 아래의 모든 사람과 공유하고 모두가 함께 토론할 수 있도록 환영합니다.

1. mvvm에는 최소한 텍스트, 모델 등과 같은 내용

  1. 명령 집합이 포함됩니다.

  2. 데이터 모델, 뷰와 상호 작용하는 데이터

  3. 구성 요소 지원: 즉, HTML 코드 일부의 동적 업데이트

2. 내 구현

1. 변수 정의 및 watch 구현

var directives = {}; //指令集合var vNodes = new Array(); //解析的Dom集合var dataModel = {
    name:"name",
    title: "title"}; //数据Modelvar Watch = {
    isInit: false,
    watchs: new Array(),
    run: function(newValue, expOrfn){ var self = this;if(!self.isInit){
            expOrfn.call(vModel);
        }this.watchs.map(function(data,index){
            data.nodes.map(function(d,i){if(self.isInit){
                    d.directive.init(newValue, d, data); //绑定初始化值, 以及初始化一些事件}else{
                    d.directive.update(newValue, d, data); //只更新值,此时run的调用来值value-set                }
            });
        });
        
        self.watchs = [];
    },
    push:function(watch){this.watchs.push(watch);
    }
} //任务管理

설명:

  1. Watch의 푸시 메서드는 종속성을 추가하는 데 사용됩니다. 그런 다음 실행하여 실행합니다. 종속성, 실행이 완료된 후 현재 종속성 컬렉션을 정리해야 합니다. vue의 종속 항목 수집은 dep에서 완료되며 watch에서 제공하는 작업 관리(제가 올바르게 이해했는지 모르겠습니다)

2. 지침 정의

directives.text = { 
    init: function(value, vNode){
        vNode.elm.textContent = value;
    },
    update: function(value, vNode){
        vNode.elm.textContent = value;
    }
}//需要响应事件的怎么办directives.model ={ 
    init: function(value, vNode, _watch){
        vNode.elm.value = value; //判断自己发生的改变,不应该再改变自己 vNode.elm.addEventListener('keyup',function(evt){
            vNode.model[_watch.key] = vNode.elm.value;
        }); 
    },
    update:function(){

    }   
}

지침:

  1. 데모 학습 예제이므로 텍스트와 모델이라는 두 가지 간단한 사양만 정의됩니다. 텍스트: 데이터 표시에 사용되고 모델은 입력(입력 상자)에 대한 응답에 사용됩니다. 3. vModel 생성

  2. //转换vModel,暂支持一级var properties = Object.getOwnPropertyNames(dataModel);var vModel = {}, formSetting = false;for( var index in properties){ 
        (function refreshData(_index){var key = properties[_index];var property = Object.getOwnPropertyDescriptor(dataModel, key);var setter = property.set;var getter = property.get;var _val = property.value;var _getter = function(){var val = getter ? getter.call(vModel) : _val;//收集依赖,与watch要分开            Watch.push({
                    key: key,
                    nodes: vNodes.filter(function(data,index){return data.modelKey == key ? true : false;
                    }),
                    getter: _getter
                });return val;
            };
            Object.defineProperty(vModel, key, {
                configurable: true,
                enumerable: true,
                set: function(value){if(setter){
                        setter.call(vModel, value);
                    } //处理依赖                Watch.run(value, _getter);//this.value = value;            },
                get: _getter
    
            })
        })(index);
    }

설명:

vModel은 dataModel을 기반으로 생성됩니다. 즉, 각 속성의 get 및 set 메소드가 사용자 정의되며 es6에서 프록시를 사용하여 구현할 수도 있습니다(

    Are 당신 말이 맞아요
  1. ). 속성을 설정할 때 get 메서드가 먼저 호출되어 종속성을 수집합니다. 편의 값을 변경한 후에는 영향을 받는 모든 콘텐츠를 수정할 수 있습니다.

  2. 4. dom을 vNode로 구문 분석

  3. //解析vNodesvar app = document.getElementById('app');
    app.childNodes.forEach(function(data,index){if(data.nodeType != 1) return;var hv = data.getAttribute('data-hv');var hvs = hv.split(',');
        hvs.forEach(function(item,row){var keyValue = item.split(':'); //vNode对象上一定要有model,这是方便vNode相应时候的找vModel        vNodes.push({
                directive: directives[keyValue[0]],
                modelKey: keyValue[1],
                model: vModel,
                elm: data
            });
        });
    });

설명:

vNode로 구문 분석한다고 말하기는 어렵습니다. 왜냐하면 이는 dom에서 data-hv로 지정된 명령만 수집하고 , elements, vModel 등이 객체를 형성하고 vModel의 각 속성의 get 메소드가 종속성을 수집할 때 참조용으로 vNodes에 저장됩니다.

  1. 5. 첫 번째 초기화

  2. //调用所有的get一次Watch.isInit = true;var _keys = Object.getOwnPropertyNames(vModel);
    _keys.map(function(key,data){var data = vModel[key];
        Watch.run(data); 
    });
    Watch.isInit = false;

지침:

여기에서는 초기화된 vModel의 값을 Dom에 렌더링합니다. 그런 다음 watch.run 메서드가 실행됩니다.

  1. 여기의 디자인과 구현이 vue의 아이디어와 일치하지 않는 것 같습니다. 누군가 이것을 본다면 조언과 지도를 부탁드립니다.

  2. 6. 구문 분석된 돔

  3. <div id="app"><span data-hv="text:title"></span><span data-hv="text:title"></span><input data-hv="model:title" /></div>

위 내용은 Vue 소스 코드를 함께 배우고 이해하세요의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.