Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Vue 3の導入を急ピッチでやってみた

Vue 3の導入を急ピッチでやってみた

2021/10/13 【シューマイ】Tech Lead Engineerから最新技術を学べ!Vue.js/Nuxt.js編 の資料です。

A83a7138276e3275d94d91ed90d13300?s=128

hecateball

October 13, 2021
Tweet

Transcript

  1. Vue 3の導入を 急ピッチでやってみた

  2. 話す人 福田 雄貴(ふくだ ゆうき) ユアマイスター株式会社 テックリード Twitter: @hecateball

  3. Vue 3って実際どうなの?

  4. なぜVue 3を導入したのか

  5. Vue 3: とにかく大量の機能アップデート • Composition API • Teleport • 非同期コンポーネントと

    <Suspense> • 複数のv-model • ルートノードを複数持つコンポーネント • filter廃止 • TypeScriptのサポート • script setup • v-bind • defineCustomElement
  6. None
  7. Composition API ロジックとコンポーネント => 疎結合 ロジックと状態(データ) => 高凝集

  8. None
  9. Nuxt3 思ってたよりやんちゃなアップデートだった ...

  10. 所感 • Vue 2とVue 3はぜんぜん違う • VueとReact (Svelte, etc...)は本質的にはそんなに違わない •

    Nuxt 3は変わり果てていて簡単に評価が出来ない
  11. Vue 3の書き方

  12. script setup

  13. script setup <script setup lang=”ts”> import EmailInput from ‘~/EmailInput.vue’ import

    PasswordInput from ‘~/PasswordInput.vue’ import { useSignIn } from ‘~/composables/auth’ const { email, password, signIn } = useSignIn() </script> <template> <form class=”form” @submit.prevent=”signIn”> <EmailInput v-model=”email” /> <PasswordInput v-model=”password” /> <button type=”submit”>サインイン</button> </form> </template> <style> .form { … } </style> defineComponent()すら めんどくさい
  14. IDEの対応も進んでいます VSCode + Volar WebStorm 2021.2.1

  15. Component Tags Order

  16. Component Tags Order <script setup lang=”ts”> import EmailInput from ‘~/EmailInput.vue’

    import PasswordInput from ‘~/PasswordInput.vue’ import { useSignIn } from ‘~/composables/auth’ const { email, password, signIn } = useSignIn() </script> <template> <form class=”form” @submit.prevent=”signIn”> <EmailInput v-model=”email” /> <PasswordInput v-model=”password” /> <button type=”submit”>サインイン</button> </form> </template> <style> .form { … } </style> <script> <template> <style>
  17. Evan YouさんのTwitterより I’ve been moving to <script> first in SFCs

    myself especially with <script setup>. It aligns better with plain JS mental model (imports & declarations first, usage next) Evan You [@youyuxi] (Aug 18th, 2021) “I’ve been moving to <script> first in SFCs myself especially with <script setup>. This tool seems to help you automate that switch :) https://twitter.com/KawamataRyo/status/1427835141833986048” Retreaved from https://twitter.com/youyuxi/status/1427982990957846529 Evan You [@youyuxi] (Aug 18th, 2021) “@reinink It aligns better with plain JS mental module (imports & declarations first, usage next)” Retreaved from https://twitter.com/youyuxi/status/1427985450598338568 Evan You [@youyuxi] (Aug 18th, 2021) “mental model*” Retreaved from https://twitter.com/youyuxi/status/1427985502704226305
  18. Component Tags Order { "plugins": [ "vue" ], "rules": {

    "vue/component-tags-order": [ "error", { "order": [ "script", "template", "style" ] } ] } } <script> <template> <style>
  19. Composition API

  20. Composition API (1) import { ref, readonly, onBeforeMount } from

    'vue' export const useItems = () => { const items = ref<Item[]>([]) // データの操作を行う関数 const refresh = async () => { const response = await fetch('/api/items') items.value = await response.json() } // ライフサイクルフックもコンポーネント外へ! onBeforeMount(refresh) // データと操作をセットで返却 // データは読み取り専用にすることでより堅牢に return { items: readonly(items), refresh } } データとロジックを ひとまとまりにして Vueコンポーネントから分離
  21. Composition API (1) import { reactive, toRefs, } from ‘vue’

    export const useSignIn = (onSuccess, onError) => { const input = reactive<SignInInput>({ email: ‘’, password: ‘’, }) const signIn = async () => { try { await signInWithEmail(input.email, input.password) onSuccess() } catch(error) { onError(error) } } return { ...toRefs(input), signIn } } データとロジックを ひとまとまりにして Vueコンポーネントから分離
  22. Composition API (1) <script setup lang=”ts”> import EmailInput from ‘~/EmailInput.vue’

    import PasswordInput from ‘~/PasswordInput.vue’ import { useSignIn } from ‘~/composables/auth’ import { useRouter } from ‘vue-router’ const router = useRouter() const { email, password, signIn } = useSignIn(() => { router.push({ name: ‘index’ }) }) </script> <template> <form class=”form” @submit.prevent=”signIn”> <EmailInput v-model=”email” /> <PasswordInput v-model=”password” /> <button type=”submit”>サインイン</button> </form> </template> データとロジックを ひとまとまりにして Vueコンポーネントから分離
  23. Composition API (2) import { ref, inject, provide, readonly, Ref,

    InjectionKey } from ‘vue’ const Modal: InjectionKey<Ref<boolean>> = Symbol() export const useModal = (injectionKey = Modal) => { const visible = inject(injectionKey, () => { const visible = ref<boolean>(false) provide(injectionKey, visible) return visible }, true) const show = () => visible.value = true const dismiss = () => visible.value = false return { visible: readonly(visible), show, dismiss } } コンポーネントを跨ぐ状態管理
  24. Composition API (2) import { createApp, ref, Plugin } from

    ‘vue’ const plugin: Plugin = (app) => { const loading = ref<boolean>(false) app.provide(‘loading-indicator’, loading) } createApp(App).use(plugin).mount(‘#app’) コンポーネントを跨ぐ状態管理
  25. チャレンジ中 コードの見通しの良さ重視 まだ破綻はしてない

  26. エンジニア 積極採用中 https://speakerdeck.com/yourmystar/engineer