Vueのコンポーネント書き方について多少考えていることがあるので整理したい。
前提
- Vue 2
- TypeScript
- vue-property-decoratorを用いたクラススタイル ( https://github.com/kaorun343/vue-property-decorator )
- Vuexをあまり使わないものとし、今回は考えない
おことわり
- Vue.extend 形式の記述には言及しない https://jp.vuejs.org/v2/guide/typescript.html#基本的な使い方
- Vuexをあまり使わないに関してはpotato4dさんの資料に書いてあった問題点あたりと大体理由はかぶるのかもしれない https://scrapbox.io/potato4d/2020%2F07%2F28_%E6%99%82%E7%82%B9%E3%81%AE_Vue_2.x_+_TypeScript_%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E8%A8%80%E3%81%88%E3%82%8B%E7%A2%BA%E3%81%8B%E3%81%AA%E3%81%93%E3%81%A8
コンポーネント分割
コンテナコンポーネントとプレゼンテーショナルコンポーネントに分けるで良いと思う https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0
コンテナコンポーネントでロジックが膨らむ問題
- Vue公式にも載ってるストアパターンを参考にするのが良さそう https://jp.vuejs.org/v2/guide/state-management.html
- SFCになるべくロジックを書かない(script部分を別のtsファイルなどに移す)
- cssなども別ファイルにしてimportする(style部分もよそに移す)
- コンポーネントクラスのフィールドはコンポーネントState型にしそこに集約する
// コンテナコンポーネント
@Component({
components: {
}
})
export default class Hoge extends Vue {
state: HogeState
}
コンテナコンポーネントでtemplateが膨らむ問題
- templateは割とどうにもならないので半分諦める
- 子コンポーネント(プレゼンテーショナルコンポーネント)ごとにpropsの型を定義してやるとtemplateのプロパティ記述は減る
- ただし@Prop形式でのプロパティの細かいオプション指定はできなくなる
- 個人的にはrequiredを子コンポーネントprops型にし、オプションのpropは個別のクラスフィールドとして@Propでマークすれば良いかみたいな気持ちになった
// プレゼンテーショナルコンポーネント
@Component({
components: {
}
})
export default class Child extends Vue {
@Prop({required: true})
props: ChildProps
@Prop({default: false})
childOption: boolean
state: ChildState
}
- props down events upをすると、コンテナコンポーネントにemitが増える。ロジックを外に逃したとしてもtemplateは膨らむ
- 複数の子コンポーネント(プレゼンテーショナルコンポーネント)がいる場合、親となるコンポーネントでは各コンポーネントのイベントをフラットにemitで受け取るため、どのコンポーネントからのevent upか分かりにくい
- 命名により区別するなど、チーム内のローカルルールで多少はさばけるかもしれないが辛そう
- emitを子コンポーネント単位で一つだけとして、イベントタイプと変更後の値などをpayloadしてもらえば親側ではFacadeぽい動きが出来て良いのかもしれないが、やりすぎ感もある
まとめ
- 妥当なとこ探っていくのが良さそう
- なんかアイデアとかペストプラクティスとか詳しい人教えて欲しい
- 新規プロジェクトでやるならVue 3とtsxでやりたいかも
0 件のコメント:
コメントを投稿