vue 공식 웹사이트에 따르면, vue는 mvvm 프레임워크이고 반응형이라는 것을 알 수 있습니다. 그 의미를 더 깊이 이해하기 위해 간단한 mvvm 학습 데모를 구현했습니다. 아래의 모든 사람과 공유하고 모두가 함께 토론할 수 있도록 환영합니다.
명령 집합이 포함됩니다.
데이터 모델, 뷰와 상호 작용하는 데이터
구성 요소 지원: 즉, HTML 코드 일부의 동적 업데이트
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); } } //任务管理
설명:
Watch의 푸시 메서드는 종속성을 추가하는 데 사용됩니다. 그런 다음 실행하여 실행합니다. 종속성, 실행이 완료된 후 현재 종속성 컬렉션을 정리해야 합니다. vue의 종속 항목 수집은 dep에서 완료되며 watch에서 제공하는 작업 관리(제가 올바르게 이해했는지 모르겠습니다)
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(){ } }
지침:
데모 학습 예제이므로 텍스트와 모델이라는 두 가지 간단한 사양만 정의됩니다. 텍스트: 데이터 표시에 사용되고 모델은 입력(입력 상자)에 대한 응답에 사용됩니다. 3. vModel 생성
//转换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에서 프록시를 사용하여 구현할 수도 있습니다(
). 속성을 설정할 때 get 메서드가 먼저 호출되어 종속성을 수집합니다. 편의 값을 변경한 후에는 영향을 받는 모든 콘텐츠를 수정할 수 있습니다.
4. dom을 vNode로 구문 분석
//解析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에 저장됩니다.
5. 첫 번째 초기화
//调用所有的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 메서드가 실행됩니다.
여기의 디자인과 구현이 vue의 아이디어와 일치하지 않는 것 같습니다. 누군가 이것을 본다면 조언과 지도를 부탁드립니다.
6. 구문 분석된 돔
<div id="app"><span data-hv="text:title"></span><span data-hv="text:title"></span><input data-hv="model:title" /></div>
위 내용은 Vue 소스 코드를 함께 배우고 이해하세요의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!