LoginSignup
8
8

More than 5 years have passed since last update.

Vue.js 2系で親コンポーネントから子コンポーネントにデータを受け渡す。

Last updated at Posted at 2017-11-15

※Vue.js初心者です。あしからず。
こんな記事をゆっくり更新しています。
Vue.js初心者の僕がつまづいたところメモ
いつか誰かのお役にたてるようにがんばっていきます。

親コンポーネントから子コンポーネントにdataを渡す。

こんな構成でブログの新規投稿画面(Editor)を作成しました。
Githubっぽいマークダウンで入力して、RailsAPIにテキストを送信します。
それにあたり、コンポーネント分割の練習をしてみました。

実装物

component_vue.png

結論:こんなコードになりました。

※コードは重要なところ以外は省略しています!

親コンポーネント

親コンポーネントEditorから子コンポーネントSubmitButtonを呼び出しています。

Editor.vue
<template>
  <!-- 省略 -->
  <SubmitButton :input="input"></SubmitButton>
</template>

<script>

import SubmitButton from "@components/parts/buttons/SubmitButton"

export default {
  name: "Editor"
  data () {
    return {
      input: ""
    }
  }
}

</script>

SubmitButton.vue

<template>
  <div id="submit" v-on:click="addFeed">Submit</div>
</template>

<script>
  import axios from "axios"

    export default {
      name: 'SubmitButton',
      props: ['input'],
      methods: {
        addFeed(e) {
          let _this = this;

          axios.post("http://localhost:3000/feeds",
            {
              feed: {
                text: this.input
              }
            }
          ).then(function(res) {
            _this.$router.push({ path: "/"})
          })
          e.preventDefault();
        }
      }
    }
</script>

ポイント

親側でv-bind, 子側でprops、そしたらthisでとれる。

Feed.vue
 <SubmitButton :input="input"></SubmitButton>

親コンポーネントで子コンポーネントを呼び出しているところで
v-bindして親コンポーネントとdataであるinputを渡してあげる。
(:input="input"の部分)

SubmitButton
export default {
  name: 'SubmitButton',
  props: ['input'],
  methods: {
    addFeed(e) {
      this.input //this.inputでアクセスできる!ワッショイヽ(゚∀゚)ノワッショイ

    }
  }
}

子コンポーネントでpropsを記述すると、
this.inputで親のdataにアクセスできるようになってる!

あとがき

データバインディングがどうとか、v-bindの挙動だとか細かい話しは正直わかっていません。また随時お勉強次第書き足していきます!

おまけ: 全コード(2コンポーネント分)

マークダウンエディタでブログ投稿画面を作成しています。

Vueのことはまだまだわかっていませんが、コンポーネント化という思想はとても好きです。JSが圧倒的に追いやすい。

Feed.vue
<template>
  <div id="feed">
    <div id="markdown-display" v-html="compiledMarkdown"></div>
  </div>
</template>

<script>
;(function() {
  var renderer = new marked.Renderer()
  renderer.code = function(code, language) {
    return '<pre'+'><code class="hljs">' + hljs.highlightAuto(code).value + '</code></pre>';
    // 参考サイト: http://phiary.me/marked-js-highlight-js, https://qiita.com/59naga/items/7d46155715416561aa60
   };

  marked.setOptions({
    renderer: renderer,
  });
})();

import axios from 'axios'
export default {
  name: 'Markdown',
  data () {
    return {
      feed: ""
    }
  },
  created() {
    axios.get('http://localhost:3000/feeds/' + this.$route.params.id)
    .then(response => {
      this.feed = response.data.text
    })
    .catch(e => {
      this.errors.push(e)
    })
  },
  computed: {
    compiledMarkdown: function() {
      return marked(this.feed, { sanitize: true })
    }
  }
}
</script>

<style scoped>
#feed {
  padding: 20px 80px;
  text-align: left;
}
</style>
SubmitButton.vue
<template>
  <div id="submit" v-on:click="addFeed">Submit</div>
</template>

<script>

import axios from "axios"

export default {
  name: 'SubmitButton',
  props: ['input'],
  computed: {
    compiledMarkdown: function() {
      return marked(this.input, { sanitize: true })
    }
  },
  methods: {
    addFeed(e) {
      let _this = this;
      console.log(this);

      axios.post("http://localhost:3000/feeds",
        {
          feed: {
            text: this.input
          }
        }
      ).then(function(res) {
        _this.$router.push({ path: "/"})
      })
      e.preventDefault();
    }
  }
}
</script>


<style scoped>
  #submit {
    position: fixed;
    bottom: 20px;
    right: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100px;
    text-align: center;
    box-shadow: 0 2px 5px rgba(0,0,0,0.26);
    height: 40px;
    cursor: pointer;
    color: #fff;
    background: #706D7F;
    border: 1px solid transparent;
    transition: all .3s;
  }

  #submit:hover {
    background: #fff;
    color: #706D7F;
    border: 1px solid #D1D9E5;
  }
</style>

8
8
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
8
8