※Vue.js初心者です。あしからず。
こんな記事をゆっくり更新しています。
Vue.js初心者の僕がつまづいたところメモ
いつか誰かのお役にたてるようにがんばっていきます。
親コンポーネントから子コンポーネントにdataを渡す。
こんな構成でブログの新規投稿画面(Editor)を作成しました。
Githubっぽいマークダウンで入力して、RailsAPIにテキストを送信します。
それにあたり、コンポーネント分割の練習をしてみました。
実装物
結論:こんなコードになりました。
※コードは重要なところ以外は省略しています!
親コンポーネント
親コンポーネント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>