公式サイトのチュートリアルから始めてみる。
初心者はvue-cliは使うべきではないと書いているが、逆らってvue-cliで始めてみるので、チュートリアルとは違ったりする。
まずは、vue-cliの各ファイルを覗いてみる。
main.jsが文字通りメインっぽい。処理の始まりって感じかな。
main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
App.vueはこんな感じ。<router-view>
って何?
App.vue
<template>
<div id="app">
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
どうやらrouter/index.js
でルーティングを設定していて、HelloWorld
コンポーネントがルートに設定されている。インデックスページにアクセスすると、HelloWorld.vue
の内容が展開されるっぽい。
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
}
]
})
テンプレート構文
テンプレート構文を使ってみる。{{}}
これのことかな。
components/HelloWorld.vue
<template>
<p>{{ message }}</p>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
message: 'hello world'
}
}
}
</script>
ディレクティブ
v-bind
ここで使っているv-bind
のようにv-
から始まる属性はディレクティブと呼ばれるらしい。
components/HelloWorld.vue
<template>
<p v-bind:title="message">title属性にmessageをbindしてるから、この文章にホバーするとmessageの内容が表示される。</p>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
message: 'hello world'
}
}
}
</script>
v-if
seen
プロパティをfalse
にすると表示されず、true
にすると表示される。
components/HelloWorld.vue
<template>
<p v-if="seen">これが見えるかな?</p>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
seen: false
}
}
}
</script>
v-for
チュートリアルには無いが、:key
が無いと怒られるので追加。
components/HelloWorld.vue
<template>
<ol>
<li v-for="todo in todos" :key="todo.text">{{ todo.text }}</li>
</ol>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
todos: [
{ text: 'やること1' },
{ text: 'やること2' },
{ text: 'やること3' }
]
}
}
}
</script>
v-on
addEventListener
的な感じ。イベントを登録することができる。
components/HelloWorld.vue
<template>
<div class="wrapper">
<p>{{ message }}</p>
<button v-on:click="reverseMessage">反対にする</button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
message: 'だまや'
}
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
}
}
</script>
v-model
これこそ、双方向データバインディングと呼ばれるもの。データを変更するとリアルタイムに表示が変わる。
components/HelloWorld.vue
<template>
<div class="wrapper">
<p>{{ message }}</p>
<input v-model="message">
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
message: 'Hello'
}
}
}
</script>
コンポーネントを作成
TodoItem.vueファイルを作成。
components/TodoItem.vue
<template>
<li>This is a todo</li>
</template>
<script>
export default {
name: 'TodoItem'
}
</script>
コンポーネントを使用
components/HelloWorld.vue
<template>
<div class="wrapper">
<ol>
<todo-item></todo-item>
</ol>
</div>
</template>
<script>
import TodoItem from './TodoItem'
export default {
name: 'HelloWorld',
components: { TodoItem },
template: '<todo-item>',
data () {
return {
message: 'Hello'
}
}
}
</script>
親のスコープから子コンポーネントにデータを渡す
components/TodoItem.vue
<template>
<li>{{ todo.text }}</li>
</template>
<script>
export default {
name: 'TodoItem',
props: ['todo']
}
</script>
components/HelloWorld.vue
<template>
<div class="wrapper">
<ol>
<todo-item v-for="item in groceryList" v-bind:todo="item" :key="item.text"></todo-item>
</ol>
</div>
</template>
<script>
import TodoItem from './TodoItem'
export default {
name: 'HelloWorld',
components: { TodoItem },
template: '<todo-item>',
data () {
return {
message: 'Hello',
groceryList: [
{ id: 0, text: '野菜' },
{ id: 1, text: 'チーズ' },
{ id: 2, text: '食べれるものならなんでも' }
]
}
}
}
</script>
親コンポーネントと子コンポーネントのファイルを同列に作成したが、本来であれば別にするべきだろうなぁ。