寝て起きて寝て

プログラミングが出来ない情報系のブログ

コンポーネント

コンポーネントとは

コンポーネントとは名前付きの再利用可能な Vue インスタンス
必要なだけ何度でも再利用できるが、宣言するたびに別のインスタンス
扱いになる為、内部に保持している変数は別で保持される。
また、「template」で設定するルート要素は単一のみなので、
複数の要素がある場合はdivで囲う必要がある。

ローカルで定義

登録したVueインスタンス配下でしか使えない。
コンテンツのサイズがグローバルのものより小さくなる

またローカルで定義した場合は削除して良いものかの判断がつきやすくなる為、

基本はローカルで定義したほうが良い

グローバルで定義

グローバルに定義されるため、一度定義すれば、どこからでも呼び出すことができる。

多く定義すると、ビルドの時間が長くなるので共通で使用するものだけ定義するべき

dataは関数で定義する必要がある。
インスタンスが返されるデータオブジェクトを独立のものにする為にこうなっている

また、componentを定義する際は、Vueインスタンス作成前に記載する必要がある

ちなみにdata部分はES6以上であれば短縮形で記載できる

Vue.component('button-counter',{
    data(){
        return{
            count:0
        }
    },
    template:'<div><span>count:<span><button v-on:click="count++">{{count}}</button></div>'
})
const app = new Vue({
    el:"#app"
})

コンポーネントの親子構造について

コンポーネントも親子構造の関係を持つことができる。

ようは、下記のように親コンポーネントの中に子コンポーネントを記載し、テンプレートを呼び出すことができる。

コンポーネント間のデータのやり取り

基本的にコンポーネントで定義したdataはそのままでは使用できないため、
アクセスできるようにする必要がある。
そのためにpropsオプションが使える。

また、子コンポーネントから親コンポーネントへ値を渡す場合には、$emitメソッドを使用する。

propsオプション

propsの値は直接変更することができない。

厳密に言うと、constのように再代入ができないだけで

オブジェクトのプロパティは変更できるので、注意が必要。

またtypeで型の制限をすることができる。

$emitメソッド

$emitメソッドの第一引数には親で定義したイベント名を定義

二つ以上の引数がある場合はその値を親コンポーネントへ渡す

公式

コンポーネントから子コンポーネントへデータを渡す

流れとしては、親コンポーネント内でv-bindで渡した値を子コンポーネント

で受け取って表示する流れになっている。

コンポーネントから親コンポーネントへデータを渡す

下記プログラムの説明は、

コンポーネントで「@update:user-name」のイベントハンドラが実行される

第二引数には変更された名前を戻り値として返す。

//子コンポーネント
const UserForm = {
  template: `
    <div>
      <div>ユーザー名変更フォーム</div>  
      <input v-model='user_name' />
      <button @click='update'>名前変更</button>
    </div>
  `,
  props: {
    userName: { type: String, required: true }
  },
  data() {
    return {
      user_name: this.userName
    }
  },
  methods: {
    update () {
      this.$emit('update:user-name', this.user_name)
    } 
  }
}

下記プログラムの説明は、

名前変更ボタン押下時に子コンポーネントのupdateメソッドで実行された$emitの処理が

コンポーネントに戻ってきたときに、$emitの第二引数で設定されたものが

$eventに入っているのでそれをuser_nameの変数に代入している。

//親コンポーネント
const UserDetail = {
  components: {
    'user-form': UserForm
  },
  data() {
    return {
      user_name: 'ヤマダ タロウ'
    }
  },
  template: `
    <div>
      <div>
        <span>ユーザー名: {{ user_name }}</span>
      </div>
      <div>
        <user-form :user-name='user_name' @update:user-name='user_name = $event'></user-form>
      </div>
            <pre>{{user_name}}</pre>
    </div>
  `
}

コンポーネントから親コンポーネントへデータを渡す(.sync修飾子を使う)

.sync修飾子を使うことで短く書くことができる。

変更後は下記

変更箇所は

<user-form :user-name.sync='user_name'></user-form>

this.$emit('update:userName', this.user_name)

の所。userNameはPropで宣言した変数名を記載する。

.sync修飾子とは

2.3.0からの機能で、子でプロパティが変更されたときに親でも変更できるようになる。

公式

スロット

コンポーネントの外部からコンポーネント内のテンプレートの任意の場所にHTMLを展開することができる

htmlのtemplate要素はVue.jsで使われるダミーの要素この中でslot属性が定義された場合

template要素内の記載がレンダリングされる

html側で特にslot属性の記載がない場合は、<slot></slot>の部分にレンダリングされる。

span要素の中にslot属性を記載した場合は、span要素ごとレンダリングされる

公式