ホームページ  >  記事  >  ウェブフロントエンド  >  Vue2.0 のライフサイクルを理解するための 1 つの記事

Vue2.0 のライフサイクルを理解するための 1 つの記事

青灯夜游
青灯夜游転載
2020-07-09 14:52:191957ブラウズ

Vue2.0 のライフサイクルを理解するための 1 つの記事

vue のライフサイクルに関する記事はインターネット上に数多くありますが、実はこの記事の原点は、公式 Web サイトに記載されている「el は新しく作成されました」という文を私が考え理解したものです。 vm.$el replace" であるため、この記事のより多くの内容は、vue ライフサイクルの "created -> beforeMount -> Mounted" プロセスを理解することにあるかもしれません。

beforeCreate --> created

この段階では、イベントが初期化され、データの観察が実行されます。

created

vue インスタンスは作成後に呼び出されますが、このときデータの観測 (データ オブザーバー)、プロパティやメソッドの操作、 watch/event イベントコールバックが完了しました。設定。

メソッド内でメソッドを呼び出し、データ内のデータにアクセスして変更し、DOM レンダリングを更新するために応答性の高い変更をトリガーし、監視内の対応するメソッドをトリガーし、再計算のために関連する属性を計算することができます。

通常、作成時に、インスタンス データを初期化するための ajax リクエストが作成されます。

現時点では、vm.$el は表示されません。

created --> beforeMount

## このプロセスでは、

a.まず、インスタンスに el オプションがあるかどうかを確認します。ある場合は、コンパイルを続行します。そうでない場合は、コンパイルは停止し、vm.$mount(el) が呼び出されるまで続行されません (el はマウントされた DOM ノードです);

b. 次に、インスタンスにテンプレートがあるかどうかを確認します。存在する場合は、テンプレートとして rander 関数にコンパイルします。

c. テンプレートがない場合は、

マウントします。 DOM 要素の html (つまり、el に対応する DOM 要素とその内部要素) が抽出され、テンプレートとしてコンパイルされます;

*注: el に対応する DOM 要素vue インスタンスが後でマウントされると、el に対応する DOM 要素とその内部要素が、テンプレートによってレンダリングされた新しい DOM に置き換えられるため、 body/html 要素にすることはできません。

d インスタンス オブジェクトに rander 関数がある場合、レンダリング操作はそれを通じて直接実行されます。

優先度: ランダー関数>テンプレート>外部HTML

現時点では、 rander 関数の準備が完了し、初めて呼び出されます。

このプロセスでは、$el はインスタンス内の el オプションに対応する DOM 要素に初期化されます。したがって、beforeMount の場合は、次を使用します。 vm.$el が取得するのは、DOM 要素をマウントする HTML です。

beforeMount

beforeMount が呼び出されると、この時点で $el が表示されます。

beforeMount -->mounted

このプロセスでは、

el が新しく作成された vm.$el に置き換えられ、インスタンスが完了します取り付け。つまり、インスタンス内の el オプションは、テンプレートのレンダリングによって作成された DOM 要素に置き換えられ、ページ内のマウント ポイントは、レンダリングされた vue インスタンスのコード セグメントに置き換えられます。

Mounted

この時点で、インスタンスは DOM にマウントされており、インスタンス内の DOM ノードは DOM API を通じて取得できます。コンソールで vm.$el を出力すると、以前のマウント ポイントとコンテンツが新しい DOM に置き換えられていることがわかります。

栗を通してこの 2 つのプロセスを見てみましょう。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/vue/2.5.13/vue.min.js"></script>
</head>
<body>
<div id="app">
    <a id=&#39;ela&#39; href="">{{message}}</a>
</div>
</body>
<script>
    var app = new Vue({
        el: '#app',
        data: function () {
            return {
                message: 'hello'
            };
        },
        template: '<p id="elp">{{message}}</p>',
        beforeMount: function () {
            console.group('beforeMount 挂载前状态===============》');
            let state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            let a = document.getElementById('ela');
            let p = document.getElementById('elp');
            console.log(this.$el);
            console.log(state);
            console.log(a);    // <a id=&#39;ela&#39; href="">{{message}}</a>
            console.log(p);     // null
        },
        mounted: function () {
            console.group('mounted 挂载结束状态===============》');
            let state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            let a = document.getElementById('ela');
            let p = document.getElementById('elp');
            console.log(this.$el);
            console.log(state);
            console.log(a);    // null
            console.log(p);     // <p id="elp">father</p>
        }
</script>
</html>

テンプレート/ランダー オプションの使用は、コンソールで明確に確認できます。マウントが完了すると、el は新しく作成された vm.$el に置き換えられます。

マウント前は、初期 el と仮想 DOM の形式で存在します。このとき、テンプレートの内容がテンプレートとして使用されます。テンプレートの内容は非表示で、出力される p タグは null です。

ハングロード後、テンプレートによってレンダリングされた新しい DOM が元の el を置き換えます。元の el に対応する DOM は存在せず、出力された a タグは null です。

beforeUpdate と updated

データ オブジェクト内のデータが更新されると、beforeUpdate フックがトリガーされます。この時点では、ビュー レイヤーは更新されていません。 beforeUpdate については、次の点に注意する必要があります:

a.

beforeUpdate をトリガーするには、更新されたデータをテンプレート内で直接または間接的に使用する必要があります;

#b,

マウントする前に、data 内のデータ更新は beforeUpdate をトリガーしません。 つまり、create および beforeMount 中にデータを変更しても更新プロセスはトリガーされません; c. データの値が beforeUpdate で再度変更されると、beforeUpdate フックが再度トリガーされ、更新が行われます。という処理が2回行われます。

更新、ビュー レイヤーが更新されました。

(上記のコードに 2 つのフックを追加)

mounted: function () {
    this.message = 'first';
//     this.show = false;        // 由于模板中没有用到show,所以show的改变不会触发beforeUpdate
},
beforeUpdate: function () {
    console.group('beforeUpdate 更新前状态===============》');
    let elp = document.getElementById('elp').innerHTML;
    console.log('message:' + this.message);
    console.log('DOM:' + elp);
},
updated: function () {
    console.group('updated 更新完成状态===============》');
    let elp = document.getElementById('elp').innerHTML;
    console.log('message:' + this.message);
    console.log('DOM:' + elp);
}

这里需要注意一点:view层我们需要通过innerHTML获取对应元素节点中的内容,而不能直接获取元素节点。直接获取元素节点,在控制台打印出来的view层中的数据都是更新之后的状态,不能打印出实时的正确的值,这应该和Chrome控制台的输出有关。

针对第三条,我们看一下下面的代码演示:

mounted: function () {
    this.message = 'first';
},
beforeUpdate: function () {
    console.group('beforeUpdate 更新前状态===============》');
    let elp = document.getElementById('elp').innerHTML;
    console.log('message:' + this.message);
    console.log('DOM:' + elp);
    this.message = 'second';    // 此时在beforeUpdate中再次修改了message的值
},
updated: function () {
    console.group('updated 更新完成状态===============》');
    let elp = document.getElementById('elp').innerHTML;
    console.log('message:' + this.message);
    console.log('DOM:' + elp);
}

 

这里我们可以清楚的看到进行了两次更新流程,但是对打印的结果有些疑问:第一次将message的值改为first,并且以first来渲染更新DOM,那么第一次调用updated时,message和DOM中的值都应该是first,而此时打印出来的时second。我理解的是,在第一次执行updated时,DOM就已经完成了第二次渲染更新,具体的过程还需要通过之后对源码的学习去理解。这里各位有不同的理解或者更详细的解释,可以在评论区留言,共同学习。

在这里,我们可以在beforeUpdate中加定时器去修改message的值,就可以等待第一次数据改变,DOM更新渲染完成后,进行第二次数据改变。

beforeUpdate: function () {
    console.group('beforeUpdate 更新前状态===============》');
    let elp = document.getElementById('elp').innerHTML;
    console.log('message:' + this.message);
    console.log('DOM:' + elp);
    var that = this;
    setTimeout(function(){
      that.message = 'second';
    });
//    this.message = 'second';    // 此时在beforeUpdate中再次修改了message的值
},

这里可以清楚看到两次数据改变时,数据和view层的更新状态。

beforeDestroy 和 destroyed

beforeDestroy:实例在销毁之前调用,此时实例仍然可用。

beforeDestroy -> destroyed: Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

destroyed:vue实例销毁后调用。

结尾:关于vue生命周期就总结完毕,有错误的地方烦请指出,会及时修改!

以上がVue2.0 のライフサイクルを理解するための 1 つの記事の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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