Help us understand the problem. What is going on with this article?

ミニマムなVueファイルでcomponentの表示順を確認してみた。

どうもはじめまして。
エンジニア一年目の@mjnjvdです。

今回はアドベンドカレンダーなるものにお誘いをいただいたので、
重い腰を上げてqiita初投稿をする決意をしました!

現在案件でVueを用いたフロントエンド開発を担当しているのですが、
リロードをかけた時や画面遷移した時の画面表示の際に、小さい要素が先に表示されてしまう現象に陥ってしまいました。
そこで今回はミニマムなVueファイルにコンポーネントを持たせ、描画が行われる順序について確認していきたいと思います。

使用したファイル

VueCLIで作成したプロジェクトを使っていきます。
今回は既存のApp.vueを以下のようにしcomponents配下にも同様のクラスを当てたコンポーネントを用意しました。
さらにchild1コンポーネント内でchildAコンポーネントを呼び出している構成を取っています。
そしてそれぞれのvueファイルのmountedにconsole.logを仕込んでいます。

App.vue
<template>
  <div class="parent">
    {{text}}
    <child1/>
    <child2/>
  </div>
</template>

<script>
import child1 from './components/child1.vue'
import child2 from './components/child2.vue'

export default {
  components: {
    child1,
    child2
  },
  data(){
    return {
      text: "parent"
    }
  },
  mounted: function(){
      console.log('parent')
  }
}
</script>

<style scoped>
  .parent{
    border:solid black
  }
</style>

実際にブラウザに表示させてみると以下のようになります。
極限にシンプルですね。
sample1.png

実行結果

ではコンソール画面を開いてリロードをかけてみましょう。
結果は...
console.png

なんと!孫コンポーネントであるchildAコンポーネントから描画されていますね...
これは小さい要素から描画されてしまうのにも納得です。

苦労した点

・Unexpected console statement (no-console)と言う謎エラー
App.vueに設置したconsole.logが原因となったエラーですね。
調べたところによるとVueCLIでプロジェクトを作成した際にデフォルトの設定を用いた結果として、ESlintもインストールされ、その初期設定でnoーconsoleが有効になってしまっていたようです。
設定をいじるのもありですが今回は煩わしさに勝てずカスタム設定でプロジェクト作成をし直し解決しました。
・child1内でcilldAのインポートがうまくいかない問題
同じ階層にあるファイルなので"import childA from 'childA.vue'"と書いていたのですが"import childA from './childA.vue'"とする必要があったようです。

追記

子コンポーネントのコードについてコメントいただいたので貼り付けておきます。child2はchild1の数字とborderの色を変えたのみになります!

child1.vue
<template>
    <div>
        {{text}}
        <childA/>
    </div>
</template>

<script>
import childA from './childA.vue'

export default {
    components: {
        childA,
    },
    data(){
        return {
            text: "child1"
        }
    },
    mounted: function(){
        console.log('child1')
    }
}
</script>

<style scoped>
    div{
        border:solid blue
    }
</style>
childA.vue
<template>
    <div class="childA">
        {{text}}
    </div>
</template>

<script>
export default {
    data(){
        return {
            text: "childA"
        }
    },
    mounted: function(){
        console.log('childA')
    }
}
</script>

<style scoped>
    div.childA{
        border:solid gray
    }
</style>

最後に

いかがでしたでしょうか。
同じようにVueの描画処理に苦労している方のお役に立てれば幸いです。

それにしても自身が悩んだことを文章化するというのは非常に難しい作業ですね。(そもそも自分が悩んでいる状態なのか判断するのも難しいと感じているのですが...)
日常的にqiita投稿といかないまでも悩みを細分化して整理する作業はやってこうと思った次第であります。

次回は@shg_shgさんの投稿です!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away