ホームページ >ウェブフロントエンド >Vue.js >vueのデータ初期化(initState)の詳細説明

vueのデータ初期化(initState)の詳細説明

青灯夜游
青灯夜游転載
2020-10-30 17:57:064611ブラウズ

次の 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
    }
}

非常に多くのデータの初期化において、プロップ、メソッド、データは比較的単純です (したがって、これらはここでは紹介しません)詳細☺) 、computed と watch は比較的難しく、ロジックが複雑なので、以下では主に computed と watch について説明します (以下のコード部分は簡略化されています)。

InitState は主に、vue インスタンス内のプロパティ、メソッド、データ、計算データ、監視データを初期化します。

props を初期化するとき (initProps)、props 内の各属性が走査され、型検証、データ監視などが実行されます (props 属性に値を割り当てるときに警告をスローするフック関数) ) 供給される。

メソッドを初期化するとき (initMethods)、主にメソッド内のメソッド名が正当であるかどうかを監視します。

データを初期化するとき (initData)、observ 関数が実行され、データ内の各属性を深く走査してデータ ハイジャックを実行します。

computed を初期化するとき (initComputed)、データが data または props に既に存在するかどうかを監視します。存在する場合は、警告がスローされます。そうでない場合は、defineComputed 関数が呼び出され、データを監視し、ゲッターとプロパティをコンポーネントのプロパティにバインドします。 computed の属性の値が関数の場合、デフォルトは属性のゲッター関数になります。さらに、属性の値をオブジェクトにすることもできます。有効なフィールドは set、get、cache の 3 つだけで、それぞれ属性の 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有,抛出警告
        }
    }
}

監視 (initWatch) を初期化するとき、vm.$watch 関数が呼び出され、セッター コールバックを監視のプロパティにバインドします (コンポーネントにそのようなプロパティがない場合、正常に監視できません。プロパティは props、data、または computed に存在する必要があります)。ウォッチの属性の値が関数の場合、デフォルトは属性の setter コールバック関数です。属性の値が配列の場合、配列の内容が走査され、コールバックがそれぞれ属性にバインドされます。また、属性の値はオブジェクトにすることもでき、このときオブジェクト内のhandlerフィールドはsetterコールバック関数を表し、immediateは内部のハンドラーメソッドを即時実行するかどうか、deepは深く監視するかどうかを表します。

vm.$watch 関数は、Watcher を直接使用してオブザーバー オブジェクトを構築します。 watch の属性の値は watcher.cb として存在し、オブザーバーの更新時に watcher.run 関数で実行されます。このプロセスを理解したい場合は、以前の記事で vue 応答システムの Watcher の紹介 (observe、watcher、dep を参照) を読んでください。

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 に存在する場合、警告が表示されます。これは、このアプローチが間違っていることを意味します。したがって、一般的には、計算されたプロパティでデータを直接宣言します。同じコード スニペットで、定義された計算プロパティがコンポーネント インスタンス上にない場合、defineComputed 関数が実行され、データに対してデータ ハイジャックが実行されます。 defineComputed 関数で何が行われるかを見てみましょう。

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 応答システム - 観察、ウォッチャー、dep では、ウォッチャーの紹介で、計算された属性ウォッチャーがインスタンス化されるときに、options.lazy を設定すると述べました。 true にします。これは、計算されたプロパティの遅延評価とキャッシュ可能にするための鍵です。もちろん、キャッシュが false ではないことが前提となります。

キャッシュが false でない場合、createComputedGetter 関数が呼び出され、計算された属性のゲッター関数 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 に設定されている場合 (計算された属性ウォッチャーの options.lazy のみが true に設定されます)。依存関係が更新されるたびに、run 関数はアクティブにトリガーされませんが、watcher.dirty は に設定されます。真実。このように、計算されたプロパティが評価されると、computedGetter 関数が実行されます。computedGetter 関数は、watcher.dirty についての判定を持ちます。watcher.dirty が true の場合、watcher.evaluate が実行され、値と watcher が更新されます。 false に設定されるため、遅延評価プロセスが完了します。後で依存関係が更新されない限り、update は実行されず、watcher.dirty が true に設定されないため、再度値を取得したときに値を更新するために watcher.evaluate が実行されず、キャッシュ効果が得られます。 。

要約すると、キャッシュが false でない場合、計算されたプロパティは遅延評価されてキャッシュ可能であり、キャッシュのデフォルトは true であり、ほとんどの場合このデフォルト値を使用するため、 計算されたプロパティであると言えます。は、キャッシュ可能性を備えた遅延評価オブザーバーです。依存関係が変更され、計算された属性に初めてアクセスされた場合にのみ、新しい値が計算されます

関連する推奨事項:

2020 フロントエンド vue インタビューの質問の概要 (回答付き)

vue チュートリアル推奨事項: 2020 年最新の vue.js ビデオ チュートリアル 5 選

プログラミング関連の知識の詳細については、プログラミング教育をご覧ください。 !

以上がvueのデータ初期化(initState)の詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。