[vue2] Vue のライフサイクルとデータ監視分析

バージョン: vue2.X、ant design vue 1.7.8

1. vue のライフサイクルは何ですか?

回答: vue のライフサイクルは、コンポーネントが作成されてから初期化、マウント、更新、その他の手順を経てアンロードされるプロセスです。

現実のジグソーパズルゲームに相当し、
まず初期化段階でパズルボードと散らばったパズルを準備し、実装段階で
パズルのピースを一つずつ目標のパターンに組み立て
、絵をバックルで留めたり、新しい絵柄を配置したりします。 DIY の絵を配置する必要がある場所。
アンロード段階は、組み立てたパズルを楽しんだ後、解体して組み立てるプロセスに相当します。


2. ライフサイクルフック関数は次のとおりです。

マウントフェーズ:
beforeCreate //データ検出とデータプロキシの作成前
//データ検出とデータプロキシの作成
beforeMount //マウント前
Mounted //マウント完了
 
更新フェーズ:
beforeUpdate //更新前に更新
//
 
アンインストール (破壊)更新後のステージ:
beforeDestroy //アンインストール前
破壊されました //完全な
 
キャッシュのアンロード (KeepAlive) ステージ:
アクティブ化 //コンポーネントのページに入る 非アクティブ化 //
非アクティブ化または終了時のエラー プロンプト (ただし、コンポーネントは破壊されません)
 
フェーズ:
errorCaptured //子孫コンポーネントからエラーをキャプチャする場合
errorHandler //指定されたコンポーネントは、レンダリングおよび観察中にエラー処理関数をキャプチャしませんでした

2.1 計算されたプロパティ

computed //計算された属性
監視 //データ監視


3. ライフサイクルの実行順序

公式ドキュメントのサンプル図に従って
ここに画像の説明を挿入
ページ上で練習してください。コードは次のとおりです
ホーム 親ページ

<template>
  <div style="padding: 60px">
    <h3 style="color: red">父页面</h3>
    <a-input v-model="message" style="width: 120px"></a-input>
    <div>{
    
    {
    
     message }}</div>
    <a-input v-model="test" style="width: 220px"></a-input>
    <a-input v-model="testList" style="width: 220px"></a-input>
    <h3 style="color: red">csdn博主:{
    
    {
    
     csdnName }}</h3>

    <a-button @click="showTap">点击卸载</a-button>
    <div>-----------------------------------------</div>
    <div v-if="isHomePageShow">
      <keep-alive>
        <homePage></homePage>
      </keep-alive>
    </div>
    <a-button @click="homePageShowTap">点击隐藏/显示子组件</a-button>
  </div>
</template>

<script>
import homePage from './components/homePage.vue'
export default {
    
    
  name: 'Home',
  components: {
    
    
    homePage,
  },
  data() {
    
    
    return {
    
    
      isHomePageShow: true,
      message: 'test',
      isImmediate: '是否开启watch数据监听默认调用',
      test: '监听数据变动调用一个封装方法',
      testList: '监听数据变动调用多个封装方法',
    }
  },
  computed: {
    
    
    csdnName() {
    
    
      console.group('------computed计算属性状态------')
      const name = '鱼干~'
      console.log('%c%s', 'color:red', 'el     : ' + this.$el) //undefined
      console.log('%c%s', 'color:red', 'data   : ' + this.$data) //undefined
      console.log('%c%s', 'color:red', 'csdn博主: ' + name)
      return name
    },
  },
  watch: {
    
    
    message: {
    
    
      handler(newVal, oldVal) {
    
    
        console.group('------watch数据监听状态------')
        console.log('%c%s', 'color:red', 'el     : ' + this.$el) //undefined
        console.log('%c%s', 'color:red', 'data   : ' + this.$data) //undefined
        console.log('%c%s', 'color:red', '新值: ' + newVal, '旧值: ' + oldVal)
      },
    },
    isImmediate: {
    
    
      handler(newVal, oldVal) {
    
    
        console.group('------watch数据监听在侦听开始之后立即调用、并且无论其被嵌套多深都可侦听状态------')
        console.log('%c%s', 'color:red', 'el     : ' + this.$el) //undefined
        console.log('%c%s', 'color:red', 'data   : ' + this.$data) //undefined
        console.log('%c%s', 'color:red', '新值: ' + newVal, '旧值: ' + oldVal)
      },
      immediate: true, //该回调将会在侦听开始之后立即调用,默认是false
      deep: true, //该回调将会在被侦听的对象的属性改变时调动,无论其被嵌套多深
    },
    // 字符串方法名称
    test: 'someMethod',
    //监听数据变动调用多个封装方法
    testList: [
      'testListSomeMethod',
      function handler2(newVal, oldVal) {
    
    
        console.group('------watch数据监听调用多个封装方法状态------')
        console.log('%c%s', 'color:red', 'el     : ' + this.$el) //undefined
        console.log('%c%s', 'color:red', 'data   : ' + this.$data) //undefined
        console.log('%c%s', 'color:red', '新值: ' + newVal, '旧值: ' + oldVal)
      },
    ],
  },
  beforeCreate: function () {
    
    
    console.group('------beforeCreate创建前状态------')
    console.log('%c%s', 'color:red', 'el     : ' + this.$el) //undefined
    console.log('%c%s', 'color:red', 'data   : ' + this.$data) //undefined
    console.log('%c%s', 'color:red', 'message: ' + this.message)
  },
  created: function () {
    
    
    console.group('------created创建完毕状态------')
    console.log('%c%s', 'color:red', 'el     : ' + this.$el) //undefined
    console.log('%c%s', 'color:red', 'data   : ' + this.$data) //已被初始化
    console.dir(this.$data)
    console.log('%c%s', 'color:red', 'message: ' + this.message) //已被初始化
  },
  beforeMount: function () {
    
    
    console.group('------beforeMount挂载前状态------')
    console.log('%c%s', 'color:red', 'el     : ' + this.$el) //undefined
    console.dir(this.$el)
    console.log('%c%s', 'color:red', 'data   : ' + this.$data) //已被初始化
    console.log('%c%s', 'color:red', 'message: ' + this.message) //已被初始化
  },
  mounted: function () {
    
    
    console.group('------mounted 挂载结束状态------')
    console.log('%c%s', 'color:red', 'el     : ' + this.$el) //已被初始化
    console.dir(this.$el)
    console.log('%c%s', 'color:red', 'data   : ' + this.$data) //已被初始化
    console.dir(this.$data)
    console.log('%c%s', 'color:red', 'message: ' + this.message) //已被初始化
  },
  beforeUpdate: function () {
    
    
    console.group('beforeUpdate 更新前状态===============》')
    console.log('%c%s', 'color:red', 'el     : ' + this.$el)
    console.dir(this.$el)
    console.log('%c%s', 'color:red', 'data   : ' + this.$data)
    console.dir(this.$data)
    console.log('%c%s', 'color:red', 'message: ' + this.message)
  },
  updated: function () {
    
    
    console.group('updated 更新完成状态===============》')
    console.log('%c%s', 'color:red', 'el     : ' + this.$el)
    console.dir(this.$el)
    console.log('%c%s', 'color:red', 'data   : ' + this.$data)
    console.dir(this.$data)
    console.log('%c%s', 'color:red', 'message: ' + this.message)
  },
  beforeDestroy: function () {
    
    
    console.group('beforeDestroy 销毁前状态===============》')
    console.log('%c%s', 'color:red', 'el     : ' + this.$el)
    console.dir(this.$el)
    console.log('%c%s', 'color:red', 'data   : ' + this.$data)
    console.dir(this.$data)
    console.log('%c%s', 'color:red', 'message: ' + this.message)
  },
  destroyed: function () {
    
    
    console.group('destroyed 销毁完成状态===============》')
    console.log('%c%s', 'color:red', 'el     : ' + this.$el)
    console.dir(this.$el)
    console.log('%c%s', 'color:red', 'data   : ' + this.$data)
    console.dir(this.$data)
    console.log('%c%s', 'color:red', 'message: ' + this.message)
  },
  errorCaptured(err, vm, info) {
    
    
    console.group('errorCaptured 捕获子孙组件的错误阶段===============》')
    console.log(`错误返回: ${err.toString()}\n在哪个钩子发生的错误: ${info}\nvue实例: ${vm}`)
  },
  methods: {
    
    
    testListSomeMethod() {
    
    
      console.log('通过watch调用该testListSomeMethod方法')
    },
    someMethod() {
    
    
      console.log('通过watch调用该someMethod方法')
    },
    homePageShowTap() {
    
    
      this.isHomePageShow = !this.isHomePageShow
    },
    showTap() {
    
    
      this.$destroy('home')
    },
  },
}
</script>

ホームページのサブページ

<template>
  <div>
    <h3 style="color: red">子页面</h3>
    <div>{
    
    {
    
     message }}</div>
  </div>
</template>

<script>
export default {
    
    
  name: 'HomePage',
  data() {
    
    
    return {
    
    
      message: '这里是子组件homePage',
    }
  },
  beforeCreate: function () {
    
    
    console.group('------子组件beforeCreate创建前状态------')
    console.log('%c%s', 'color:red', 'el     : ' + this.$el) //undefined
    console.log('%c%s', 'color:red', 'data   : ' + this.$data) //undefined
    console.log('%c%s', 'color:red', 'message: ' + this.message)
  },
  created: function () {
    
    
    messageTest = '制造错误触发errorCaptured'
    console.group('------子组件created创建完毕状态------')
    console.log('%c%s', 'color:red', 'el     : ' + this.$el) //undefined
    console.log('%c%s', 'color:red', 'data   : ' + this.$data) //已被初始化
    console.dir(this.$data)
    console.log('%c%s', 'color:red', 'message: ' + this.message) //已被初始化
  },
  beforeMount: function () {
    
    
    console.group('------子组件beforeMount挂载前状态------')
    console.log('%c%s', 'color:red', 'el     : ' + this.$el) //undefined
    console.dir(this.$el)
    console.log('%c%s', 'color:red', 'data   : ' + this.$data) //已被初始化
    console.log('%c%s', 'color:red', 'message: ' + this.message) //已被初始化
  },
  mounted: function () {
    
    
    console.group('------子组件mounted 挂载结束状态------')
    console.log('%c%s', 'color:red', 'el     : ' + this.$el) //已被初始化
    console.dir(this.$el)
    console.log('%c%s', 'color:red', 'data   : ' + this.$data) //已被初始化
    console.dir(this.$data)
    console.log('%c%s', 'color:red', 'message: ' + this.message) //已被初始化
  },
  beforeUpdate: function () {
    
    
    console.group('子组件beforeUpdate 更新前状态===============》')
    console.log('%c%s', 'color:red', 'el     : ' + this.$el)
    console.dir(this.$el)
    console.log('%c%s', 'color:red', 'data   : ' + this.$data)
    console.dir(this.$data)
    console.log('%c%s', 'color:red', 'message: ' + this.message)
  },
  updated: function () {
    
    
    console.group('子组件updated 更新完成状态===============》')
    console.log('%c%s', 'color:red', 'el     : ' + this.$el)
    console.dir(this.$el)
    console.log('%c%s', 'color:red', 'data   : ' + this.$data)
    console.dir(this.$data)
    console.log('%c%s', 'color:red', 'message: ' + this.message)
  },
  beforeDestroy: function () {
    
    
    console.group('子组件beforeDestroy 销毁前状态===============》')
    console.log('%c%s', 'color:red', 'el     : ' + this.$el)
    console.dir(this.$el)
    console.log('%c%s', 'color:red', 'data   : ' + this.$data)
    console.dir(this.$data)
    console.log('%c%s', 'color:red', 'message: ' + this.message)
  },
  destroyed: function () {
    
    
    console.group('子组件destroyed 销毁完成状态===============》')
    console.log('%c%s', 'color:red', 'el     : ' + this.$el)
    console.dir(this.$el)
    console.log('%c%s', 'color:red', 'data   : ' + this.$data)
    console.dir(this.$data)
    console.log('%c%s', 'color:red', 'message: ' + this.message)
  },
  activated() {
    
    
    console.group('------activated缓存阶段,进入组件------')
    console.log('%c%s', 'color:red', 'el     : ' + this.$el) //undefined
    console.log('%c%s', 'color:red', 'data   : ' + this.$data) //undefined
    console.log('%c%s', 'color:red', 'message: ' + this.message)
  },
  deactivated() {
    
    
    console.group('------activated缓存阶段,离开或停用当前组件------')
    console.log('%c%s', 'color:red', 'el     : ' + this.$el) //undefined
    console.log('%c%s', 'color:red', 'data   : ' + this.$data) //undefined
    console.log('%c%s', 'color:red', 'message: ' + this.message)
  },
}
</script>

<style  scoped>
</style>

コンソールのスクリーンショット、印刷順序は次のとおりです。ここに画像の説明を挿入

まず、beforeCreate作成前に現在のコンポーネント インスタンスは作成されておらず、開発初期化タスクの作成に使用されます。

次に、watchデータ監視、現在の監視が即座に true に設定され、監視の開始直後にコールバックが呼び出されます。デフォルトは false です。

作成が完了した後created、el、つまり Dom 要素はこの状態ではまだ利用できませんが、データはすでに取得できています。これはデータがロードされていることを意味し、通常は非同期データの送信に使用されますcreatedここで尋ねてください

マウントする前にbeforeMountDOM ノードは作成されず、レンダリングと更新も実行されないため、el はまだそれを取得できません。

次に、computed属性を計算します。これは関数またはオブジェクト { {get,set}} にすることができます。これは一般的な関数です。セットを書き込むことはできません。複数のデータの影響を受ける値に適しており、通常は結果を返します。キャッシュがあります。属性、テンプレート内で複数回使用は 1 回だけ計算されます。


// サブコンポーネント
、次にサブコンポーネント、beforeCreate
次にサブコンポーネント、create
そしてサブコンポーネントがerrorCapturedある場合、サブコンポーネントのエラーがキャプチャされると、サブコンポーネントに問題がある場所を示すプロンプトが表示され、次にサブコンポーネント
コンポーネント、beforeMount
サブコンポーネント、beforeMount
サブコンポーネントの順activated


最後にmountedマウントが完了し、DOM ノードが作成されますが、通常は を使用してDOM ノードを取得できる$refsので$el、この段階で el を取得できます。console.dir を使用して、必要ないくつかの要素の属性を出力できます。

次に、更新フェーズでは、vue ページに次のコードがあります。

 <a-input v-model="message" style="width: 120px"></a-input>
 <div>{
    
    {
    
     message }}</div>
  <h3 style="color: red">csdn博主:{
    
    {
    
     csdnName }}</h3>

ここに画像の説明を挿入
次に、入力ボックスにメッセージ データを入力して変更します。スクリーンショットは次のとおりです。
ここに画像の説明を挿入


//計算された属性がある場合、データ監視状態watch
に入ります。これは関数またはオブジェクトにすることができます { {handler,immediate,deep}}; デフォルトの初期化は、immediate が true に設定されていない限り実行されません。 1 つの値が複数のデータに影響を与える場合に適しており、結果を返さない可能性がある複数の操作を実行する場合に適しています。非同期または高価な操作に適しています。watch


ページ要素を変更するたびに、更新フェーズに入ります。これは、beforeUpdate と updated の 2 つの状態です。
beforeUpdate更新前、通常、更新前のさまざまな状態を取得するために使用されます
update。 更新後、すべての状態が最新です


サブコンポーネントがある場合は、サブコンポーネントのシーケンスを入力および終了 (非アクティブ化) します。サブコンポーネントの
ここに画像の説明を挿入
非表示/表示ボタンをクリックすると、
ここに画像の説明を挿入
最初に親コンポーネントを入力し、beforeUpdate
次にサブコンポーネントを入力し、次にサブコンポーネントを入力し、activated
次にbeforeDestroy
サブコンポーネントを入力し、destroyed
次に親コンポーネントを入力します。コンポーネントactivated


次に、アンロード (破棄) フェーズで、vue の親に新しいコードが追加されます。

//在template代码块增加如下按钮
  <a-button @click="showtap">点击卸载</a-button>
 //在script增加一个方法
  methods: {
    
    
    showtap() {
    
    
      this.$destroy('home')
    },
  },

アンインストールボタンをクリックした後のスクリーンショットは次のとおりです。ここに画像の説明を挿入

beforeDestroy破棄前の状態、要素、データは破棄前に出力でき、通常はタイマーや購読解除などに使用され、コンポーネント インスタンスはこの時点でもまだ存在します


// サブコンポーネントがある場合は
activated
サブコンポーネントが破棄されるbeforeDestroy前の状態に入り
、サブコンポーネントはdestroyed完了した状態を破棄します。


destroyed破棄の完了ステータスも出力できます。コンポーネントは破棄されており、現時点ではコンポーネント インスタンスは存在しません。

beforeDestroyと はdestroyed、このコンポーネントを終了するときにのみ呼び出されるライフサイクルです。

4. まとめ

ライフサイクル:

別名: ライフ サイクル コールバック関数、ライフ サイクル関数、ライフ サイクル フック。
それは何ですか: 重要な瞬間に Vue が呼び出す特別な名前を持ついくつかの関数。
ライフサイクル関数の名前は変更できませんが、関数の具体的な内容は要件に応じてプログラマによって記述されます。
ライフサイクル関数の this は、vm またはコンポーネント インスタンス オブジェクトを指します。
 
一般的に使用されるライフサイクル フック:

マウント: Ajax リクエストの送信、タイマーの開始、カスタム イベントのバインド、メッセージのサブスクライブなど [初期化操作]。
beforeDestroy: タイマーのクリア、カスタム イベントのバインド解除、メッセージの購読解除など [仕上げ作業]。
 
Vue インスタンスの破棄について
破棄後は、Vue 開発者ツールを使用して情報を表示できなくなります。
カスタム イベントは破棄後は無効になりますが、ネイティブ DOM イベントは引き続き有効です。
一般に、beforeDestroy ではデータは操作されません。データが操作されたとしても、更新プロセスが再度トリガーされることはないからです。
 
公式サイトhttps ://cn.vuejs.org/api/options-lifecycle.html#beforecreate

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_43861689/article/details/129714989