>  기사  >  웹 프론트엔드  >  vue의 데이터 초기화(initState)에 대한 자세한 설명

vue의 데이터 초기화(initState)에 대한 자세한 설명

青灯夜游
青灯夜游앞으로
2020-10-30 17:57:064543검색

다음 Vue.js 튜토리얼 열에서는 vue의 데이터 초기화(initState)를 안내합니다. 도움이 필요한 친구들이 모두 참고할 수 있기를 바랍니다.

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, 메소드 및 데이터가 비교적 간단하므로(그래서 자세히 소개하지는 않겠습니다☺), 계산 및 감시는 비교적 간단합니다. 간단합니다. 어렵습니다. 로직이 복잡하므로 아래에서는 계산 및 관찰에 대해 주로 설명하겠습니다. (다음 코드 부분은 단순화되었습니다.)

initState는 주로 vue 인스턴스의 props, 메서드, 데이터, 계산 및 감시 데이터를 초기화합니다.

props(initProps) 초기화 시 props에 포함된 각 속성을 순회한 후 타입 검증, 데이터 모니터링 등을 수행합니다(props 속성에 값을 할당할 때 경고를 던지는 Hook 기능)를 제공합니다.

메서드 초기화(initMethods) 시 주로 메소드에 포함된 메소드 이름이 적법한지 여부를 모니터링합니다.

데이터(initData)를 초기화할 때 관찰 기능이 실행되어 데이터의 각 속성을 심층적으로 탐색하여 데이터 하이재킹을 수행합니다.

computed(initCompulated)를 초기화할 때 데이터가 이미 데이터 또는 props에 존재하는지 여부를 모니터링합니다. 존재하는 경우 경고가 발생합니다. 그렇지 않으면 defineCompulated 함수가 호출되어 데이터를 모니터링하고 getter 및 setter를 바인딩합니다. 구성 요소의 속성에. 계산의 속성 값이 함수인 경우 기본값은 속성의 getter 함수입니다. 또한 속성 값은 객체일 수도 있습니다. 여기에는 각각 속성의 setter, getter 및 캐싱 활성화 여부를 나타내는 set, get 및 캐시의 세 가지 유효한 필드만 있으며 캐시 기본값은 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)를 초기화할 때 vm.$watch 함수가 호출되어 setter 콜백을 watch의 속성에 바인딩합니다(구성 요소에 해당 속성이 없으면 성공적으로 모니터링할 수 없습니다. 속성이 존재해야 함) 소품, 데이터 또는 계산). watch의 속성 값이 함수인 경우 기본값은 속성의 setter 콜백 함수입니다. 속성 값이 배열이면 배열의 내용이 순회되고 콜백이 각각 속성에 바인딩됩니다. 또한, 속성의 값은 객체일 수도 있으며, 이때 객체의 핸들러 필드는 setter 콜백 함수를 나타내고,immediate는 내부 핸들러 메소드를 즉시 실행할지 여부를 나타내며, deep은 심층적으로 모니터링할지 여부를 나타냅니다.

vm.$watch 함수는 Watcher를 직접 사용하여 관찰자 개체를 구성합니다. watch의 속성값은 watcher.cb로 존재하며, 관찰자가 업데이트할 때 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 === &#39;string&#39;) {
        handler = vm[handler];
    }
    //为属性创建侦听器
    return vm.$watch(expOrFn, handler, options)
}

computed

computed는 본질적으로 캐시 가능성이 있는 게으른 평가 관찰자입니다. 종속성이 변경되고 계산된 속성에 처음으로 액세스할 때만 새 값이 계산됩니다

다음에서는 이에 대해 중점적으로 설명합니다. 설명하는 한 문장입니다.

위 코드에서 언급한 것처럼 계산된 속성의 데이터가 data와 props에 존재할 경우 경고가 표시되는데, 이는 이 접근 방식이 잘못되었음을 의미합니다. 따라서 일반적으로 계산된 속성에서 데이터를 직접 선언합니다. 동일한 코드 조각에서 정의된 계산 속성이 구성 요소 인스턴스에 없으면 정의 계산 함수가 실행되어 데이터에 대한 데이터 하이재킹을 수행합니다. DefineCompulated 함수에서 수행되는 작업을 살펴보겠습니다.

function defineComputed(target, key, userDef) {
//是不是服务端渲染
var shouldCache = !isServerRendering();
//如果我们把计算属性的值写成一个函数,这时函数默认为计算属性的get
if(typeof userDef === &#39;function&#39;) {
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로 설정된다고 언급했습니다. 계산된 속성의 지연 평가 및 캐시 가능(물론 캐시가 false가 아닌 경우).

cache가 false가 아닌 경우 createCompulatedGetter 함수가 호출되어 계산된 속성의 getter 함수인 ComputedGetter를 생성합니다.

먼저 코드를 살펴보겠습니다.

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의 게으른 속성이 true로 설정됨) 종속성이 업데이트될 때마다 실행 함수가 적극적으로 트리거되지 않지만 watcher.dirty는 true로 설정됩니다. 이런 식으로 계산된 속성이 평가되면 계산된 Getter 함수가 watcher.dirty에 대한 판단을 갖고 watcher.dirty가 true인 경우 watcher.evaluate가 실행되어 값과 더티를 업데이트합니다. false로 설정되어 지연 평가 프로세스가 완료됩니다. 나중에 종속성이 업데이트되지 않는 한 업데이트는 실행되지 않으며 watcher.dirty는 true로 설정되지 않습니다. 그러면 값을 다시 얻을 때 값을 업데이트하기 위해 watcher.evaluate가 실행되지 않으므로 캐시 효과가 달성됩니다. .

요약하자면, 캐시가 false가 아닌 경우 계산된 속성은 지연 평가되고 캐시 가능하며 캐시의 기본값은 대부분 이 기본값을 사용하므로 computed本质是一个惰性求值的观察者,具有缓存性,只有当依赖变化后,第一次访问 computed 属性,才会计算新的值라고 말합니다.

관련 권장 사항:

2020 프론트엔드 vue 인터뷰 질문 요약(답변 포함)

vue 튜토리얼 권장 사항: 2020년 최신 5 vue.js 비디오 튜토리얼 선택

더 많은 프로그래밍 관련 지식을 원하시면 문의하세요. 방문: 프로그래밍 교육! !

위 내용은 vue의 데이터 초기화(initState)에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제