Rodhos Soft

備忘録を兼ねた技術的なメモです。Rofhos SoftではiOSアプリ開発を中心としてAndroid, Webサービス等の開発を承っております。まずはご相談下さい。

Vue.JS コンポーネントの使い方

簡単な例 components

<template>
  <div>
    <p>myConponent</p>
 </div>
</template>

スクリプト

<script>
/* eslint-disable */
import { defineComponent, computed, watch } from '@vue/composition-api';
export default defineComponent({
  name: 'MyCard',
  components: {},
  props: {},
  data: function() {},
  created: function() {},
  mounted: function() {},
  methods: {},
  computed: {},
  filters: {},
  watch: {},
  directives: {}
});
</script>

<style>
</style>

としておく。から実装のところはなくて良い。nameのMyCardを使う。

使いたい親は

スクリプト内で

<script>
/* eslint-disable */
import { defineComponent, computed, watch } from '@vue/composition-api';
import MyCard from '@/components/MyCard.vue';

export default defineComponent({
  name: 'Hoge',
  components: { 'my-cards': MyCard },

のように、MyCardを<my-cards>として使うようにする。これで親では

<my-cards></my-cards>

として使えるようになる。タグ名はケバブ表記にすること。

親から値を渡したい。 props

子の方でpropsを定義しておく

import { defineComponent, computed, watch } from '@vue/composition-api';
import { bus } from '../views/Hoge.vue';
export default defineComponent({
  name: 'MyCard',
  components: {},

  props: {
    cardValue: {
      type: String,
      required: true // 必須条件
    },
    otherCardValue: { name: String },
    chName: String,
    chAge: Number
  },

これはcardValueに関しては値を必ず入れる必要があり、ほかはそうでもない。

子はpropを普通の変数のように

<p>{{ cardValue }}</p>

などで参照できる。

実際に親が値を渡しているのは

 <my-cards cardValue="fromParent"
              v-bind:otherCardValue="watchedData"
              v-on:helloFromChild="handleHelloFromChild"
              v-on:countUpRequest="handleCountUpRequest"
              v-bind:chName.sync="myName"
              v-bind:chAge.sync="myAge"
              >

otherCardValueの値は親のwatchedDataにバインドされているのでwatchedDataが変わればotherCardValueは変わる。 v-bind:chName.sync="myName"は双方向バインディングで 子から更新の依頼を

    localChAge: {
      get: function() {
        return this.chAge;
      },
      set: function(val) {
        this.$emit('update:chAge', val); // syncしている値を更新する
      }

のように$emitをつかって飛ばしてやる必要がある。

子から親への呼び出し $emit

hello: function() {
      this.$emit('helloFromChild', 'MyName');
    },

親は予め

<my-cards cardValue="fromParent"
              v-bind:otherCardValue="watchedData"
              v-on:helloFromChild="handleHelloFromChild"

のように、呼ばれるものを登録しておく必要がある。これでhandleHelloFromChildが呼ばれる。

イベントバスによるやりとり Vueをbusようにする。

親側でbusとするVueを作っておく。

import Vue from 'vue'

export let bus = new Vue();// イベントバス用

export default defineComponent({
  name: 'Hoge',
  components: { 'my-cards': MyCard },

親側でcreatedのライフサイクルで何を受け取るか登録する。 $on

  created: function() {
    // イベントバス登録
    bus.$on("BusEvent", function (message) {
      alert(message);
    })


  },

子側でイベントバスに対して$emitすれば連絡が行く。

helloBusEvent: function() {
      bus.$emit('BusEvent', 'BusEvent!');
    },

スロットを使って親からタグをまるごと渡して子のスロット部分にはめる。 slot

子のテンプレートで入れてもらいたいところにslotタグを置く、slotが複数あるときはnameをつける。値を渡したいときは属性をつける(fromChildSlotValue)。

<template>
  <div>
    <p>myConponent</p>
    <div>
      <slot name="slot1" fromChildSlotValue="ThisIsFromChildSlotValue!"></slot>
    </div>
    <div>
      <slot name="slot2" fromChildSlotValue="ThisIsFromChildSlotValue!"></slot
      >
    </div>
  </div>
</template>

親側はスロットになるものを用意し、slotにslot名を入れる。子からもらえる変数はslot-scope="hoge"でまとめてもらえる。今の場合hoge.fromChildSlotValueで参照可能になる。

<my-cards cardValue="fromParent">
              <div slot="slot1" slot-scope="props">
                <p>slotされた所 {{props.fromChildSlotValue}}</p>
              </div>
              <div slot="slot2" slot-scope="props">
                <p>slotされた所2! {{props.fromChildSlotValue}}</p>
              </div>
    </my-cards>