【Vue.js】scriptブロックの肥大化を防ぐ
はじめに
Vue.jsを使った開発でtemplate部分の分割については、いろいろな記事などがあると思います。
筆者が参画したいくつかのプロジェクトでは、template部分の分割については、ある程度対応しているケースもありましたが、scriptブロックにはJaveScript, TypeScriptが大量に書かれており、ソースコードを読むのに苦労したケースが多々ありました。今回参画したプロジェクトでは、その反省を生かし、scriptブロックの肥大化を防ぐ方法をいくつか実践しましたので、その備忘も兼ねてご紹介していきたいと思います。
通常のvue
何をもって通常なのかという話はありますが、vue.jsで開発をするとこのようなになると思います。これはこれでよいですが、開発するプロダクトの規模によっては、1,000行を軽く超えるようなファイルが出来上がってしまうこともしばしばあります。
<script setup>
import { ref } from 'vue'
const text = ref('')
function onInput(e) {
text.value = e.target.value
}
</script>
<template>
<input :value="text" @input="onInput" placeholder="Type here">
<p>{{ text }}</p>
</template>
composablesとしてモジュール化する
composablesとは、Composition API を活用して状態を持つロジックをカプセル化して再利用するための関数になります。
上記のscriptブロックの部分をcomposables化すると下記のようになります。
import { ref } from 'vue'
export function useOnInput() {
const text = ref('')
function onInput(e) {
text.value = e.target.value
}
return { text, onInput }
}
<script setup>
import { useOnInput } from 'src/composables/useOnInput.js'
const { text, onInput } = useOnInput()
</script>
<template>
<input :value="text" @input="onInput" placeholder="Type here">
<p>{{ text }}</p>
</template>
このサンプルですとイメージがわきにくいかもしれませんが、このように外部に分割した関数を使用することで、vueファイル側のscriptブロックの記述量を少なく保つことができます。
ご参考)
storeを利用する
composablesのほかには、piniaを使いました。
import { defineStore } from 'pinia'
export const useStore = defineStore('useStore', {
state: () => ({
text: '',
}),
actions: {
onInput(e) {
this.$patch({ text: e.taget.value })
},
},
})
<script setup>
import { useStore } from 'src/stores/useStore.js'
const store = useStore()
</script>
<template>
<input :value="store.text" @input="store.onInput" placeholder="Type here">
<p>{{ text }}</p>
</template>
同じサンプルで大変恐縮ですが、piniaを使うことでもvueファイル側のscriptブロックの記述量を少なく保つことができます。
おわりに
簡単なサンプルではありますが、composablesやstoreを活用することで、vueファイルの記述量を減らすことができますので、是非活用していただければと思います。
Discussion