LoginSignup
5
0

More than 3 years have passed since last update.

【Vue.js】はじめてのVue.js〜コンポーネント〜

Last updated at Posted at 2021-02-15

JavaScriptのフレームワークである「Vue.js」についての記事です。学習途中で至らない点等あると思うのですが、備忘録兼自分と同じ初学者の方向けにまとめてみました。

現在はVue.jsを用いてポートフォリオを書き換えつつ、学習を進めています。記述したコードも用いているので、是非参考にしてみてください。ポートフォリオはこちら、GitHubはこちらのページをご覧ください。

ポートフォリオ内の学習スキルを記述した以下の部分
代替テキスト
を例にコンポーネントの書き方をまとめています。

インスタンス、ディレクティブに関する記事はこちらをご覧ください。

目次

  1. コンポーネント
    1. コンポーネントとは
    2. メリット
    3. 書き方
    4. Vue.component
    5. templete
    6. props

1. コンポーネント

1.1 コンポーネントとは

再利用することのできる部品。
本記事のはじめに載せたポートフォリオ内のskillsの項目のように、大枠のフォーマットを踏襲しつつ、中身だけ変えて使い回すことができる。

1.2 メリット

  • HTMLファイルのコードが簡潔になり分かりやすい。
  • 大枠のDOM要素の変更が生じても、jsファイルの一箇所を直せば全てに適応されるので管理が楽。

jsファイルに以下のようなインスタンスが定義してあり、インスタンスのdataオプションオブジェクト内のskills配列の中身を全て表示したいとする。

main.js
const skills = new Vue({
    el:'#skills',
    data:{
        skills:[
            {
                id:'frontend_skills',
                show:'フロントエンド',
                icon:true,
                details:[
                    'HTML',
                    'CSS',
                    'JavaScript',
                    'jQuery',
                ],
            },
            {
                id:'backend_skills',
                show:'バックエンド',
                icon2:true,
                details:[
                    'php(Laravel)',
                ],
            },
            {
                id:'database_skills',
                show:'DataBase',
                icon3:true,
                details:[
                    'MySQL',
                    'Realtime<br>Database',
                ],
            },
            {
                id:'infrastructure_skills',
                show:'インフラ',
                icon4:true,
                details:[
                    'AWS(EC2,S3)',
                ],
            },
            {
                id:'others',
                show:'その他',
                icon5:true,
                details:[
                    'git',
                    'GitHub',
                    'firebase',
                    'Heroku',
                    'Bootstrap',
                ],
            },
            {
                id:'studying',
                show:'学習中',
                icon6:true,
                details:[
                    'Sass',
                    'Vue.js',
                    'React',
                ],
            },
        ],
    },
})

一つの手として、以下のようにHTMLファイルに直接書き込む方法がある。
見ての通り、6つの項目が続くためとても長い。また、DOM要素の変更が生じた際、6箇所直す必要がありミスが生じやすい。項目が6つだからなんとかなるが、項目の数がもっと多い場合は大変である・・・

index.html
<section id="skills">
    <div>
        <h5><i class="fas fa-pen"></i>Skills<i class="fas fa-pen"></i></h5>
    </div>

    <div id="frontend_skills">
        <h6><i class="fab fa-html5"></i>フロントエンド</h6>
        <div>
            <ul>
                <li>HTML</li>
                <li>CSS</li>
                <li>JavaScript</li>
                <li>jQuery</li>
            </ul>
        </div>
    </div>

    <div id="backend_skills">
        <h6><i class="fab fa-html5"></i>バックエンド</h6>
        <div>
            <ul>
                <li>php(Laravel)</li>
            </ul>
        </div>
    </div>

    <div id="database_skills">
        <h6><i class="fab fa-html5"></i>DataBase</h6>
        <div>
            <ul>
                <li>MySQL</li>
                <li>Realtime<br>Database</li>
            </ul>
        </div>
    </div>

    <div id="infrastructure_skills">
        <h6><i class="fab fa-html5"></i>インフラ</h6>
        <div>
            <ul>
                <li>AWS(EC2,S3)</li>
            </ul>
        </div>
    </div>

    <div id="others">
        <h6><i class="fab fa-html5"></i>その他</h6>
        <div>
            <ul>
                <li>git</li>
                <li>GitHub</li>
                <li>firebase</li>
                <li>Heroku</li>
                <li>Bootstrap</li>
            </ul>
        </div>
    </div>

    <div id="studying">
        <h6><i class="fab fa-html5"></i>学習中</h6>
        <div>
            <ul>
                <li>Sass</li>
                <li>Vue.js</li>
                <li>React</li>
           </ul>
        </div>
    </div>
</section>

そこで登場するのがコンポーネント。実際に使用するとHTMLファイルを以下のように書き換えることができる。見ての通り、とてもシンプル!!!

index.html
<section id="skills">
    <div>
        <h5><i class="fas fa-pen"></i>Skills<i class="fas fa-pen"></i></h5>
    </div>

    <skills-component
        v-for="skill in skills"
        v-bind:key="skill.id"
        v-bind:skill="skill"
    ></skills-component>
</section>

1.3 書き方

main.js
Vue.component('skills-component',{
    props:['skill'],
    template:`
        <div v-bind:id="skill.id">
            <h6><i v-bind:class="{'fab fa-html5':skill.icon,'fab fa-php':skill.icon2,'fas fa-database':skill.icon3,'fas fa-network-wired':skill.icon4,'fab fa-github-square':skill.icon5,'fas fa-pen':skill.icon6}"></i>{{ skill.show }}</h6>
            <div>
                <ul class="skills">
                    <li v-for="detail in skill.details" v-html="detail"></li>
                </ul>
            </div>
        </div>
    `
})

今回のコードに出てきたVue.componentpropstemplateの3つの説明をしつつ、書き方を整理していく。

1.4 Vue.component

main.js
Vue.component('skills-component',{
    props:[''],
    template:'',
})

Vue.componentメソッドを呼び出すことでコンポーネントを作成することができる。

第1引数には、コンポーネントにつける名前を渡す。もとから用意されてるHTML要素の名前とかぶるのを防ぐために、複数の単語を組み合わせて名前をつける。今回はskillsを表示するコンポーネントと言うことで、skill-componentという名前にしている。
第2引数には、コンポーネントの内容などをオプションとして渡す。今回は propstempleteを渡している。

これにより、skills-componentというオリジナルの要素をHTMLファイルで使用することができる。

1.5 templete

コンポーネントの中身を決めるもの。

中身は単一ルートである必要があるため、以下のような記述だとエラーが出る。解決策としては、全てをdiv要素で囲んで一つのDOM要素にしてしまう。

main.js
Vue.component('skills-component',{
    //propsは省略
    template:`
        <h6><i v-bind:class="{'fab fa-html5':skill.icon,'fab fa-php':skill.icon2,'fas fa-database':skill.icon3,'fas fa-network-wired':skill.icon4,'fab fa-github-square':skill.icon5,'fas fa-pen':skill.icon6}"></i>{{ skill.show }}</h6>
        <div>
            <ul class="skills">
                <li v-for="detail in skill.details" v-html="detail"></li>
            </ul>
        </div>
    `
})

このコンポーネントを、インスタンスのdataオプションオブジェクト内のskills配列の中身全てに使用するために、コンポーネント自体にv-forディレクティブを用いている。今回は配列から取り出したものをskillという変数に格納し、繰り返し処理をしている。

index.html
<section id="skills">
    <skills-component
        v-for="skill in skills"
    ></skills-component>
</section>

では、繰り返し処理をする中で、それぞれ異なった値を表示させるためにはどのようにすればいい???
そこで登場するのがpropsオプジョン。

1.6 props

コンポーネントに値を渡す架け橋になるもの。

以下の場合、コンポーネントにインスタンスのdataオプションオブジェクト内のskills配列の要素のid,show,detailsプロパティを渡している。

今回はskills配列から取り出したものをskillという変数に格納し、繰り返し処理をしている。skillの持つプロパティを全て渡す場合、以下のようにプロパティをprops:['skill']として書くこともできる。「skillの変数が持つ全てのプロパティを渡しますよ〜」ということを表している。
渡すプロパティが多くなるとコードが長くなってしまうため、こちらの書き方の方が良い。

main.js
Vue.component('skills-component',{  
    //一つずつプロパティを書く方法
    props:[
        'id',
        'show',
        'details',
    ],

    //全てのプロパティを一気に書く方法
    props:['skill'],

    //templeteは省略

そして、以下のようにカスタム属性(propsで指定したプロパティのこと)を通してプロパティの値を受け取らせる。

index.html
<section id="skills">
    <!-- 一つずつプロパティを書く方法 -->
    <skills-component
        v-for="skill in skills"
        v-bind:id="skill.id"
        v-bind:show="skill.show"
        v-bind:details="skill.details"
    ></skills-component>

    <!-- 全てのプロパティを一気に書く方法 -->
    <skills-component
        v-for="skill in skills"
        v-bind:skill="skill"
    ></skills-component>
</section>

以上で、コンポーネントのテンプレートにプロパティを渡すことができるため、繰り返し処理の中で、その都度異なった値を表示することができる。

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0