欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue?先初始化父組件再初始化子組件的方法(自定義父子組件mounted執(zhí)行順序)

 更新時間:2024年07月09日 09:33:09   作者:Dandelion  
這篇文章主要介紹了Vue?先初始化父組件再初始化子組件的方法(自定義父子組件mounted執(zhí)行順序),本篇內(nèi)容內(nèi)容主要講述了,在使用?Konva?進(jìn)行開發(fā)過程中遇到的一些問題,需要的朋友可以參考下

寫在前面:

本篇內(nèi)容內(nèi)容主要講述了,在使用 Konva 進(jìn)行開發(fā)過程中遇到的一些問題。(既然是組件加載順序,主要牽扯到的就是,父子組件的關(guān)系,父子組件的生命周期)

眾所周知,Vue中父子組件生命周期的執(zhí)行順序?yàn)椋?/p>

// 掛載階段
父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted
// 更新階段
父beforeUpdate -> 子beforeUpdate -> 子updated -> 父updated
// 銷毀階段
父beforeDestroy -> 子beforeDestroy -> 子destroyed -> 父destroyed
  • 然而,在某些情況下我們有其他需求,例如我們不得不讓子組件的初始化在父組件初始化完成之后再進(jìn)行(一般是針對mounted),下面將進(jìn)行詳細(xì)說明

1、引用關(guān)系說明

  • 最終目的:使用Konva 庫繪制組件,該組件由兩個按鈕、一個電平表、一個增益控制推桿,這些子組件組合起來構(gòu)成所需組件,并將其繪制到Stage中的Layer
    • StageLayer只有一個,所以應(yīng)當(dāng)寫在App.vue中,使用時將Layer傳遞給子組件(且這個Layer應(yīng)當(dāng)是響應(yīng)式的);且由于要繪制所需組件,因此自然是要引用所需組件,即所需組件是App.vue的子組件
    • 所需組件應(yīng)當(dāng)引用各個子組件,它是各個子組件的父親
  • 綜上,是一個三層的繼承關(guān)系,此外,由于有了StageLayer才能繪制所需組件,有了所需組件才能繪制各個子組件,此時,各個控件的初始化順序與生命周期剛好相反。

2、兩層繼承關(guān)系示例

假如說目前我只有兩層繼承關(guān)系,App.vue 和所需組件 Channel.vue

代碼在下方展示,詳細(xì)的內(nèi)容我將在代碼中使用注釋詳細(xì)說明,請按照注釋編號順序進(jìn)行閱讀和理解

App.vue

要點(diǎn):

  • layer 依賴注入,使所有的子組件可以獲取
  • 父組件的 layer 進(jìn)行依賴注入時需要使用響應(yīng)式,以便于父組件知道 layer 的改變(類比C語言的直接傳參和指針傳參)
  • 需要將所需組件引用、注冊并展示到頁面上
<template>
  <div id="app">
    <div id="frame">
      <!-- 7. 將所需子組件展示到頁面 -->
      <Channel />
    </div>
  </div>
</template>
<script>
import Konva from 'konva';
import { computed } from 'vue';
// 5. 引入所需組件用于繪制和頁面展示
import Channel from './components/Channel.vue';
export default {
  // 2. 父組件將 layer 傳遞給子組件,子組件沒有 layer 就無法繪制組件
  provide() {	// 依賴注入,所有子組件可獲取
    return {
      // 3. 傳遞給子組件的 layer應(yīng)當(dāng)是響應(yīng)式的,否則對子組件的修改無法同步到父組件的layer
      layer: computed(() => this.layer),      // 4. 響應(yīng)式的區(qū)別,類比C語言的直接傳參和指針傳參
    }
  },
  components: {
    // 6. 注冊子組件
    Channel,
  },
  mounted() {
    // 0.初始化組件
    this.initializeKonva();
    window.addEventListener("resize", this.handleResize);
  },
  beforeUnmount() {
    window.removeEventListener("resize", this.handleResize);
  },
  data() {
    return {
      stage: null,
      layer: null,
    };
  },
  methods: {
    initializeKonva() {
      this.stage = new Konva.Stage({
        container: "frame",
        width: window.innerWidth,
        height: window.innerHeight,
      });
      // 1. 這里為了解耦和效率,全局使用一個layer
      this.layer = new Konva.Layer();
      this.stage.add(this.layer);
    },
    handleResize() {
      this.stage.width(window.innerWidth);
      this.stage.height(window.innerHeight);
      this.stage.batchDraw();
    },
  },
};
</script>
<style scoped>
    /* 樣式細(xì)節(jié)不表 */
</style>
 
  • layer 依賴注入,使所有的子組件可以獲取
  • 父組件的 layer 進(jìn)行依賴注入時需要使用響應(yīng)式,以便于父組件知道 layer 的改變(類比C語言的直接傳參和指針傳參)
  • 需要將所需組件引用、注冊并展示到頁面上
  • Channel.vue

    要點(diǎn):

    • 接收 layer

    • 使用 this.$nextTick(() => { 初始化代碼 }),會使得初始化代碼在父組件的初始化完成后再執(zhí)行

      • this.$nextTick()Vue.js提供的一個方法,用于在DOM更新之后執(zhí)行回調(diào)函數(shù)。它的作用是確保在下次DOM更新循環(huán)結(jié)束之后執(zhí)行回調(diào)函數(shù),以確保操作的準(zhǔn)確性和可靠性。

      • Vue.js中,當(dāng)數(shù)據(jù)發(fā)生改變時,Vue會異步地更新DOM。這意味著在修改數(shù)據(jù)后立即訪問更新后的DOM可能無法得到正確的結(jié)果,因?yàn)榇藭rDOM可能尚未完成更新。

        通過使用this.$nextTick()方法,我們可以將回調(diào)函數(shù)延遲到下一次DOM更新循環(huán)之后執(zhí)行。在這個時候,Vue已經(jīng)完成了所有的異步DOM更新,我們可以放心地操作更新后的DOM元素,確保獲取到準(zhǔn)確的結(jié)果。

    • 繪制完成后更新 layer

<template>
    <div>
        <div ref="container"></div>
    </div>
</template>
<script>
import Konva from 'konva';
export default {
    // 1. 接收父組件依賴注入的 layer 
    inject: ['layer'],
    components: {},
    data() {return {};},
    mounted() {
        // 2. 使用 this.$nextTick(() => {}),在DOM更新之后執(zhí)行回調(diào)函數(shù)
        this.$nextTick(() => {
            // 3. 初始化
            this.initializeKonva();
        });
    },
    methods: {
        initializeKonva() {
            this.group = new Konva.Group({
                // ...
            });
            const backgroundRect = new Konva.Rect({
               // ...
            });
            const textTop = new Konva.Text({
                // ...
            });
            this.textLevel = new Konva.Text({
                // ...
            });
            this.textGain = new Konva.Text({
                // ...
            });
            const textBottom = new Konva.Text({
                // ...
            });
            const line1 = new Konva.Line({
                // ...
            });
            const line2 = new Konva.Line({
                // ...
            });
            const line3 = new Konva.Line({
                // ...
            });
            this.group.add(backgroundRect, textTop, this.textLevel, this.textGain, textBottom, line1, line2, line3);
            // 4. layer 是通過依賴注入傳遞,inject接收的,使用 this 訪問
            this.layer.add(this.group);
            // 5. 更新 layer
            this.layer.draw();
        },
    },
};
</script>
<style></style>
  

3、三層及以上繼承關(guān)系示例

  • 在上面的內(nèi)容中,使用this.$nextTick(() => { 回調(diào) })解決了兩層繼承關(guān)系中的反向初始化順序的問題。
  • 但是這本質(zhì)上更像是一種小聰明,當(dāng)?shù)搅巳龑右陨侠^承關(guān)系的時候這種方法不能有任何效果,因?yàn)樽咏M件和孫子組件如果不同時使用 this.$nextTick(() => { 回調(diào) }) 總會有人在父組件之前初始化,而如果都用了 this.$nextTick(() => { 回調(diào) }) 那么它們兩個本身的初始化順序仍然是先子后父,一定會出問題。所以要使用其他的方式來解決這個問題

代碼在下方展示,詳細(xì)的內(nèi)容我將在代碼中使用注釋詳細(xì)說明,請按照注釋編號順序進(jìn)行閱讀和理解

  • Channel.vue

    要點(diǎn):

    • 接收 layer 等不再贅述
    • 使用 this.$nextTick(() => { 初始化代碼 }),會使得初始化代碼在父組件的初始化完成后再執(zhí)行
    • 設(shè)置flag用于判斷當(dāng)前組件初始化是否完成,使用v-if="flag"控制子組件初始化時機(jī)
<template>
    <div>
        <div ref="container"></div>
        <!-- 3. v-if="flag" 控制子組件的初始化時機(jī) -->
        <SwitchButton :btnNameIndex="0" :x="0" :y="group.height() / 17 + group.height() / 17 / 4" :parent="this.group"
            v-if="flag" />
        <SwitchButton :btnNameIndex="1" :x="0" :y="group.height() / 17 * 3 - group.height() / 17 / 3" :parent="this.group"
            v-if="flag" />
        <!-- 4. :parent="this.group" 將this.group傳遞給子組件,命名為parent,這種傳遞方式默認(rèn)為響應(yīng)式,無需其他操作 -->
        <LevelMeter :x="0" :y="group.height() / 17 * 4 + group.height() / 17 / 2" :parent="this.group" v-if="flag"
            @levelChangeEvent="handleLevelChange" />
        <Gain :x="0" :y="group.height() / 17 * 4 + group.height() / 17 / 4" :parent="this.group" v-if="flag"
            @dBChangeEvent="handleDBChange" />
    </div>
</template>
<script>
import Konva from 'konva';
import SwitchButton from './SwitchButton.vue';
import LevelMeter from './LevelMeter.vue';
import Gain from './Gain.vue';
export default {
    inject: ['layer'],
    components: {
        SwitchButton,
        LevelMeter,
        Gain,
    },
    data() {
        return {
            // ...
            // 0. 準(zhǔn)備一個flag用于確認(rèn)初始化時機(jī)
            flag: false,
            group: null,
        };
    },
    mounted() {
        // 1. 存在父親,切需要使用父親中的 layer ,等待父組件初始化完成
        this.$nextTick(() => {
            this.initializeKonva();
            // 2. 使用flag判斷是否已經(jīng)初始化完成
            this.flag = true;
        });
    },
    methods: {
        initializeKonva() {
            // ...
            this.layer.add(this.group);
            this.layer.draw();
        },
        handleDBChange(newDB) {
            // ...
        },
        handleLevelChange(newLevel) {
            // ...
        },
    },
};
</script>
<style></style>
  

到此這篇關(guān)于Vue 先初始化父組件再初始化子組件的方法(自定義父子組件mounted執(zhí)行順序)的文章就介紹到這了,更多相關(guān)vue自定義父子組件mounted執(zhí)行順序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue.js中ref及$refs的使用方法解析

    vue.js中ref及$refs的使用方法解析

    這篇文章主要介紹了vue.js中ref及$refs的使用方法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10
  • vuex的核心概念和基本使用詳解

    vuex的核心概念和基本使用詳解

    這篇文章主要為大家介紹了vuex的核心概念和基本使用,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • Vue中的methods、watch、computed的區(qū)別

    Vue中的methods、watch、computed的區(qū)別

    這篇文章主要介紹了Vue中的methods、watch、computed的區(qū)別,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • Vue自定義Hook實(shí)現(xiàn)簡化本地存儲

    Vue自定義Hook實(shí)現(xiàn)簡化本地存儲

    這篇文章主要為大家詳細(xì)介紹了如何通過使用 Vue 3 的 Composition API 創(chuàng)建一個強(qiáng)大而靈活的自定義 Hook,簡化了在 localStorage 或 sessionStorage 中管理數(shù)據(jù)的流程,需要的可以參考下
    2023-12-12
  • vue2中如何使用swiper@5.4.5

    vue2中如何使用swiper@5.4.5

    這篇文章主要介紹了vue2中如何使用swiper@5.4.5問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • vue與iframe頁面數(shù)據(jù)互相通信的實(shí)現(xiàn)示例

    vue與iframe頁面數(shù)據(jù)互相通信的實(shí)現(xiàn)示例

    這篇文章主要給大家介紹了vue與iframe頁面數(shù)據(jù)互相通信的實(shí)現(xiàn)示例,文中通過代碼示例給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-12-12
  • vue動態(tài)配置模板 ''component is''代碼

    vue動態(tài)配置模板 ''component is''代碼

    這篇文章主要介紹了vue動態(tài)配置模板 'component is'代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-07-07
  • Vue記事本實(shí)例詳解

    Vue記事本實(shí)例詳解

    這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)記事本功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • Vue引入并使用Element組件庫的兩種方式小結(jié)

    Vue引入并使用Element組件庫的兩種方式小結(jié)

    本文主要介紹了Vue引入并使用Element組件庫的兩種方式小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • vue 根據(jù)選擇條件顯示指定參數(shù)的例子

    vue 根據(jù)選擇條件顯示指定參數(shù)的例子

    今天小編就為大家分享一篇vue 根據(jù)選擇條件顯示指定參數(shù)的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11

最新評論