vue 데이터 초기 화 initState 의 인 스 턴 스 상세 설명

데이터 초기 화
Vue 인 스 턴 스 는 만 들 때 일련의 초기 화 작업 을 실행 합 니 다.이 초기 화 작업 에서 데이터 바 인 딩 과 가장 큰 관 계 를 가 진 것 은 initState 입 니 다.
우선,그의 코드 를 살 펴 보 자.

function initState(vm) {
 vm._watchers = [];
 var opts = vm.$options;
 if(opts.props) {
  initProps(vm, opts.props); //   props
 }
 if(opts.methods) {
  initMethods(vm, opts.methods); //   methods
 }
 if(opts.data) {
  initData(vm); //   data
 } else {
  observe(vm._data = {}, true /* asRootData */ );
 }
 if(opts.computed) {
  initComputed(vm, opts.computed); //   computed
 }
 if(opts.watch && opts.watch !== nativeWatch) {
  initWatch(vm, opts.watch); //   watch
 }
}
이렇게 많은 데이터 의 초기 화 에서 props,methods 와 data 는 비교적 간단 하 다.☺),한편,coptute d 와 watch 는 상대 적 으로 어렵 고 논리 가 복잡 하기 때문에 저 는 주로 coptute d 와 watch(아래 코드 부분 은 간략화 된 것)를 말씀 드 리 겠 습 니 다.
initState 에 서 는 vue 인 스 턴 스 의 props,methods,data,coptute d 와 watch 데 이 터 를 초기 화 합 니 다.
props 를 초기 화 할 때(initprops)props 의 모든 속성 을 옮 겨 다 니 며 유형 검증,데이터 모니터링 등(props 속성 할당 에 경 고 를 던 지 는 갈고리 함수 제공).
methods 를 초기 화 할 때(initMethods)는 주로 methods 의 방법 명 이 합 법 적 인지 모니터링 합 니 다.
data 를 초기 화 할 때(initData)observe 함수 깊이 가 데이터 의 모든 속성 을 옮 겨 다 니 며 데이터 납 치 를 합 니 다.
computed 를 초기 화 할 때(initComputed)데이터 가 data 나 props 에 존재 하 는 지 모니터링 하고 존재 하면 경 고 를 던 집 니 다.그렇지 않 으 면 define Computed 함수,감청 데 이 터 를 호출 하여 구성 요소 의 속성 에 getter 와 setter 를 연결 합 니 다.컴퓨터 d 에서 속성의 값 이 함수 라면 기본적으로 속성의 getter 함수 입 니 다.또한 속성의 값 은 하나의 대상 일 수 있 습 니 다.그 는 세 개의 유효한 필드 set,get,cache 만 있 습 니 다.각각 속성 을 나타 내 는 setter,getter 와 캐 시 를 사용 할 지 여 부 를 표시 합 니 다.그 중에서 get 은 필수 입 니 다.cache 는 기본 값 은 true 입 니 다.

function initComputed(vm, computed) {
 var watchers = vm._computedWatchers = Object.create(null);

 for(var key in computed) {
  var userDef = computed[key];
  var getter = typeof userDef === 'function' ? userDef : userDef.get;

  //         watcher
  watchers[key] = new Watcher(
   vm,
   getter || noop,
   noop,
   computedWatcherOptions
  );

  if(!(key in vm)) {
   //                ,         
   //defineComputed    ,      
   defineComputed(vm, key, userDef);
  } else {
   //          data props ,    
  }
 }
}
watch 를 초기 화 할 때(initWatch)함 수 를 watch 의 속성 바 인 딩 setter 로 호출 합 니 다(구성 요소 에 이 속성 이 없 으 면 감청 에 성공 하지 못 합 니 다.속성 은 props,data 또는 coptute 에 존재 해 야 합 니 다).watch 에서 속성의 값 이 함수 라면 기본 값 은 속성의 setter 리 셋 함수 입 니 다.속성의 값 이 하나의 배열 이 라면 배열 의 내용 을 옮 겨 다 니 며 속성 바 인 딩 리 셋 입 니 다.그 밖 에 속성의 값 은 하나의 대상 일 수도 있 습 니 다.이때 대상 중의 handler 필드 는 setter 리 셋 함 수 를 대표 합 니 다.immediate 는 즉시 안의 handler 방법 을 실행 하 는 지 여 부 를 대표 합 니 다.deep 대표 님,심도 있 는 감청 여 부 를 말씀 드 리 겠 습 니 다.vm.$watch함 수 는 Watcher 를 직접 사용 하여 관찰자 대상 을 구축한다.watch 에 있 는 속성의 값 은 watcher.cb 로 존재 합 니 다.관찰자 update 를 관찰 할 때 watcher.run 함수 에서 실 행 됩 니 다.이 과정 을 알 고 싶 으 면 제 전편 vue 응답 식 시스템 인 observe,watcher,dep 에서 Watcher 에 대한 소 개 를 볼 수 있 습 니 다.

function initWatch(vm, watch) {
 //  watch,           
 for(var key in watch) {
  var handler = watch[key];
  //          ,     ,          
  //createWatcher      vm.$watch,  vm.$watch      
  if(Array.isArray(handler)) {
   for(var i = 0; i < handler.length; i++) {
    createWatcher(vm, key, handler[i]);
   }
  } else {
   //        
   createWatcher(vm, key, handler);
  }
 }
}

function createWatcher(vm, expOrFn, handler, options) {
 //          ,     handler      
 if(isPlainObject(handler)) {
  options = handler;
  handler = handler.handler;
 }
 //           ,         
 if(typeof handler === 'string') {
  handler = vm[handler];
 }
 //        
 return vm.$watch(expOrFn, handler, options)
}
computed
coptute d 는 본질 적 으로 타성 구 치 를 하 는 관찰자 로 캐 시 성 을 가지 고 있 으 며,변화 에 의존 한 후에 처음으로 coptute d 속성 을 방문 해 야 새로운 값 을 계산 할 수 있 습 니 다.
다음은 이 한 마디 를 둘러싸 고 설명 하 겠 습 니 다.
위 코드 에서 언급 한 바 와 같이 계산 속성 에 있 는 데이터 가 data 와 props 에 존재 할 때 경 고 를 받는다.즉,이런 방법 은 잘못된 것 이다.그래서 일반적으로 우 리 는 계산 속성 에서 데 이 터 를 직접 설명 합 니 다.아니면 그 코드 세 션 에서 정 의 된 계산 속성 이 구성 요소 인 스 턴 스 에 없 으 면 define Computed 함 수 를 실행 하여 데 이 터 를 납치 합 니 다.다음은 define Computed 함수 에서 무엇 을 했 는 지 살 펴 보 겠 습 니 다.

function defineComputed(target, key, userDef) {
 //        
 var shouldCache = !isServerRendering();
 //                 ,            get
 if(typeof userDef === 'function') {
  sharedPropertyDefinition.get = shouldCache ?
   //         ,       ,  get createComputedGetter       
   createComputedGetter(key) :
   //       ,    get userDef         
   userDef;
  //  set    
  sharedPropertyDefinition.set = noop;
 } else {
  //                 ,       set、get cache    
  sharedPropertyDefinition.get = userDef.get ?
   shouldCache && userDef.cache !== false ?
   //       get  ,        , cache  false,  get createComputedGetter       
   createComputedGetter(key) : 
   //       get  ,          cache   false,  get userDef         
   userDef.get :
   //      get  ,  get    
   noop;
  //  set        set      
  sharedPropertyDefinition.set = userDef.set ?
   userDef.set :
   noop;
 }
 //      get、set         
 //      ,get            ,set            
 // computed           ,  get      
 //    
 Object.defineProperty(target, key, sharedPropertyDefinition);
}
지난 편vue 응답 시스템--observe,watcher,dep에서 저 는 Watcher 에 관 한 소개 에서 속성 watcher 를 계산 할 때 options.lazy 를 true 로 설정 합 니 다.여 기 는 속성 타성 구 치 를 계산 하고 캐 시 할 수 있 는 관건 입 니 다.물론 전 제 는 cache 가 false 가 아 닙 니 다.
cache 는 false 가 아 닙 니 다.createComputedGetter 함 수 를 호출 하여 속성 을 계산 하 는 getter 함수 coptute dGetter 를 만 듭 니 다.
코드 부터 볼 게 요.

function createComputedGetter(key) {
 return function computedGetter() {
  var watcher = this._computedWatchers && this._computedWatchers[key];
  if(watcher) {
   if(watcher.dirty) {
    //watcher.evaluate   watcher  ,  watcher.dirty   false
    //               watcher.dirty   true,                   
    watcher.evaluate();
   }
   //    
   if(Dep.target) {
    watcher.depend();
   }
   //  watcher  
   return watcher.value
  }
 }
}
//      ,        ,       watcher dirty true
//          ,      ,              。
Watcher.prototype.evaluate = function evaluate() {
 this.value = this.get();
 this.dirty = false;
};
//          ,   update
Watcher.prototype.update = function update() {
 //  watcher,       watcher lazy   true,        
 if(this.lazy) {
  this.dirty = true;
 } else if(this.sync) {
  //            run,      ,         queueWatcher
  this.run();
 } else {
  // watcher        ,   tick   。
  //                ,          
  queueWatcher(this);
 }
};
options.lazy 가 true 로 설정 되면(속성 watcher 만 계산 하 는 options.lazy 는 true 로 설정)업데이트 에 의존 할 때마다 run 함 수 를 주동 적 으로 터치 하지 않 고 watcher.dirty 를 true 로 설정 합 니 다.이렇게 계산 속성 을 추출 할 때 computedGetter 함 수 를 실행 합 니 다.computedGetter 함수 에서 watcher.dirty 에 대한 판단 이 있 습 니 다.watcher.dirty 가 true 일 때 watcher.evaluate 를 실행 하여 값 을 업데이트 하고 watcher.dirty 를 false 로 설정 하면 타성 구 치 를 완성 합 니 다.다음 에 업데이트 에 의존 하지 않 으 면 update 를 실행 하지 않 고 watcher.dirty 를 true 로 하지 않 습 니 다.그러면 다시 값 을 추출 할 때 watcher.evaluate 를 실행 하지 않 고 값 을 업데이트 하여 캐 시 효 과 를 얻 을 수 있 습 니 다.
다시 말 하면 우 리 는 cache 가 false 가 아니 라 는 것 을 알 았 을 때 계산 속성 은 모두 타성 구 치 였 고 캐 시 성 이 있 었 다.cache 는 기본적으로 true 였 다.우 리 는 대부분 이 기본 값 을 사용 했다.그래서 우 리 는 computed 본질 은 타성 구 치 의 관찰자 이 고 캐 시 성 이 있 으 며 변화 에 의존 한 후에 처음으로 computed 속성 을 방문 해 야 새로운 값 을 계산 할 수 있다 고 말 했다.
총결산
위 에서 말 한 것 은 소 편 이 소개 한 vue 데이터 초기 화 initState 의 실례 상세 한 설명 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.소 편 은 제때에 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
만약 당신 이 본문 이 당신 에 게 도움 이 된다 고 생각한다 면,전 재 를 환영 합 니 다.출처 를 밝 혀 주 십시오.감사합니다!

좋은 웹페이지 즐겨찾기