初めに
仕事でたまにVue.jsを使う機会があるのですが、よく分かっていなかったので一から学びました。
学んだことをアウトプットします。
使用したサイト
全15章。今回は9~15章。
https://ja.vuejs.org/tutorial/#step-1
学習メモ
ライフサイクルとテンプレート参照
ref属性でテンプレートの要素を参照、操作することができるようになる
ref属性の付与された要素はthis.$refs.[値]で参照できるようになる
コンポーネントがマウントされるまでrefにアクセスはできない
vueではmounted()オプションを用いることで、マウント後のコンポーネントにアクセスできる
created()とmounted()は両方ともライフサイクルフックだが、タイミングが異なる。
created()はDOM生成前。mounted()はDOM生成後。
<script type="module">
import { createApp } from 'vue'
createApp({
mounted() {
this.$refs.pElementRef.textContent = "mounted!"
}
}).mount('#app')
</script>
<div id="app">
<p ref="pElementRef">Hello</p>
</div>
ウォッチャー
プロパティの値が変更された時に実行する処理を定義できる
以下の例は、todoIdの値が変わった時にthis.fetchData()を行う処理をウォッチャーで定義している。
<script type="module">
import { createApp } from 'vue'
createApp({
data() {
return {
todoId: 1,
todoData: null
}
},
watch: {
todoId() {
this.fetchData()
}
},
methods: {
async fetchData() {
this.todoData = null
const res = await fetch(
`https://jsonplaceholder.typicode.com/todos/${this.todoId}`
)
this.todoData = await res.json()
}
},
mounted() {
this.fetchData()
}
}).mount('#app')
</script>
<div id="app">
<p>Todo id: {{ todoId }}</p>
<button @click="todoId++" :disabled="!todoData">Fetch next todo</button>
<p v-if="!todoData">Loading...</p>
<pre v-else>{{ todoData }}</pre>
</div>
コンポーネント
コンポーネントから別のコンポーネントを使用することができる(親と子)
親コンポーネントから利用するには
①子コンポーネントをインポートする
②インポートした子コンポーネントをcomponentsオプションに記載する
③componentsオプションに記載した子コンポーネントをケバブケースにしたタグをHTMLで使用する
<script type="module">
import { createApp } from 'vue'
import ChildComp from './ChildComp.js'
createApp({
components: {
ChildComp
}
}).mount('#app')
</script>
<div id="app">
<child-comp></child-comp>
</div>
export default {
template: `
<h2>A Child Component!</h2>
`
}
props
子コンポーネント呼び出しで引数を渡すことができる
propsオプションに引数を定義し、親コンポーネントから呼び出す際にv-bindで指定する
<script type="module">
import { createApp } from 'vue'
import ChildComp from './ChildComp.js'
createApp({
components: {
ChildComp
},
data() {
return {
greeting: 'Hello from parent'
}
}
}).mount('#app')
</script>
<div id="app">
<child-comp v-bind:msg="greeting"></child-comp>
</div>
export default {
props: {
msg: String
},
template: `
<h2>{{ msg || 'No props passed yet' }}</h2>
`
}
イベントの発行
子コンポーネントから親コンポーネントにデータを受け渡すためには、emitという機能を使用する
親コンポーネントでイベントの処理を定義しておき、子コンポーネントから呼びだす
親コンポーネントでは<child-comp @response="(msg) => childMsg = msg"></child-comp>という形でイベントを定義しておく
子コンポーネントでは
①emitsオプションで使用するイベント名を宣言
②任意の箇所でthis.$emit('イベント名', 引数)という形で親コンポーネントで用意したイベントを呼び出す
<script type="module">
import { createApp } from 'vue'
import ChildComp from './ChildComp.js'
createApp({
components: {
ChildComp
},
data() {
return {
childMsg: 'No child msg yet'
}
}
}).mount('#app')
</script>
<div id="app">
<child-comp @response="(msg) => childMsg = msg"></child-comp>
<p>{{ childMsg }}</p>
</div>
export default {
emits: ['response'],
watch: {
value() {
this.$emit('response', this.value)
}
},
data() {
return {
value: ''
}
},
template: `
<h2 v-mode>Child component</h2>
<input v-model="value"></input>
<div>{{value}}</div>
`
}
スロット
propsと同様、親コンポーネントから値を受け渡すことができる
子コンポーネントで<slot></slot>のように記載した個所について、親コンポーネントのスロットコンテンツをレンダリングすることができる
<script type="module">
import { createApp } from 'vue'
import ChildComp from './ChildComp.js'
createApp({
components: {
ChildComp
},
data() {
return {
msg: 'from parent'
}
}
}).mount('#app')
</script>
<div id="app">
<child-comp>Test!!!</child-comp>
</div>
export default {
template: `
<slot>Default Value</slot>
`
}
終わりに
vue.jsのチュートリアルはとても分かりやすく、ブラウザ上でできるので非常に手軽でした。
入門としては間違いないと思うので、これから始めてみたい型は是非試してみてください。
ここまでご覧いただきありがとうございました!