Vue.jsコンポーネント間の通信(非親子・兄弟の場合)


#背景

```<script>``` タグを直接組み込み！
すべてのコードを一つhtmlに書く！
コンポーネントは親子じゃない！
の場合、
コンポーネント間の通信はどうすればいいの？

###Vue.prototype.bus  を使いましょう！

#UI

コンポーネント二つある

コンポーネント1：datepicker
コンポーネント2：logvalue

動作：
confirmボタンを押すと、
コンポーネント[datepicker]で選択した日付をコンポーネント[logvalue]に反映できる
![スクリーンショット 2019-11-01 13.49.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181748/20ac92a2-b626-9a50-f928-71ad650d8fe7.png)


#実装の説明



編集中・・少々を待ち


#完成版のhtml

```コンポーネント.html
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">

  <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>

  <title>兄弟コンポーネント間の通信</title>

</head>

<style>
  .box-card {
    width: 300px;
  }

  .el-header {
    background-color: #ffffff;
    color: #333;
    text-align: center;
    line-height: 60px;
    font-size: larger;
  }

  .el-row {
    margin-bottom: 20px;
  }

  .display-none {
    display: none;
  }
</style>



<body>
  <div id="app">
    <el-container>
      <el-header>兄弟コンポーネント間の通信</el-header>
      <el-main>
        <el-row>
          <router-view class="datepicker" name="datepicker"></router-view>
        </el-row>
        <router-view  class="logvalue" name="logvalue"></router-view>
      </el-main>
    </el-container>
  </div>
</body>

<script type="text/x-template" id="datePicker">
  <div class="block">
    <span id="datevalue" class="display-none">{{ dateValue }}</span>
    <el-tooltip class="item" effect="light" content="Pick a day" placement="top-start">
    <el-date-picker
      v-model="dateValue"
      type="date"
      format="yyyy/MM/dd"
      value-format="yyyyMMdd"
      placeholder="Pick a day">
    </el-date-picker>
    </el-tooltip>
      <el-button type="primary" @click="abtn">confirm</el-button>
    </div>
</script>

<script type="text/x-template" id="logvalueShow">
  <el-card class="box-card">
  <div class="logvalue">
   <span class="display" id="acceptDate" @passData="acceptdataEvent">{{acceptData}}</span>
</div>
</el-card>
</script>

<script>
  //componentsの間を通信できるようにVue.prototype.busを作成
  window.Vue.prototype.bus = new Vue()

  //componentsのtemplateを作成
  const logvalue = {
    template: '<log-value></log-value>'
  }
  const datepicker = {
    template: '<date-picker></date-picker>'
  }


  //component[datepicker]を定義
  Vue.component('date-picker', {
    data:function() {
      return {
        dateValue: null
      }
    },
    methods: {
      getdatatime:function() {
        var date = new Date();
        var s1 = date.getFullYear() + "" + (date.getMonth() + 1) + "" + (date.getDate());
        this.dateValue = s1;　　 
      },
      abtn: function() {
        this.bus.$emit("passData", this.dateValue)
      }

    },
    mounted:function() {
      let that = this;
      that.getdatatime()
    },
    template: '#datePicker'
  })


  //todayを定義
  var today = dateToStr24H(new Date(), 'YYYYMMDD');
  //フォーマットする自作関数
  function dateToStr24H(date, format) {
    if (!format) {
      format = 'YYYYMMDD'
    }
    //フォーマット文字列内のキーワードを日付に置換する
    format = format.replace(/YYYY/g, date.getFullYear());
    format = format.replace(/MM/g, ('0' + (date.getMonth() + 1)).slice(-2));
    format = format.replace(/DD/g, ('0' + date.getDate()).slice(-2));
    return format;
  }
  //console.log(today);



  //component[logvalue]を定義
  Vue.component('log-value', {
    data:function() {
      return {
        logs: [],
        acceptData: null
      }
    },
    mounted:function() {
      let that = this;
      this.bus.$on('passData', function(data) {

        that.acceptData = data;

      })
    },
    created: function() {
      this.acceptdataEvent();
    },
    methods: {
      acceptdataEvent: function() {
        let that = this;
        this.bus.$on('passData', function(data) {
          this.acceptData = data;
        })
      }
    },
    template: '#logvalueShow'
  })

  const routes = [{
      path: '/login',
      components: {
        logvalue: logvalue,
        datepicker: datepicker
      }
    },
    {
      path: '*',
      redirect: '/login'
    }
  ];
  const router = new VueRouter({
    routes:routes
  });


  router.beforeEach(function(to, from, next)  {
    if (to.matched.some(function(record) {record.meta.requiresAuth})) {
      if (!auth.loggedIn()) {
        next({
          path: '/login',
          query: {
            redirect: to.fullPath
          }
        })
      } else {
        next()
      }
    } else {
      next()
    }
  });


  var vm = new Vue({
    router:router,
    el: '#app'
  })
</script>

</html>


```