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

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

hecateball
October 13, 2021

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

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

hecateball

October 13, 2021
Tweet

More Decks by hecateball

Other Decks in Programming

Transcript

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

    <Suspense> • 複数のv-model • ルートノードを複数持つコンポーネント • filter廃止 • TypeScriptのサポート • script setup • v-bind • defineCustomElement
  2. 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()すら めんどくさい
  3. 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>
  4. 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
  5. Component Tags Order { "plugins": [ "vue" ], "rules": {

    "vue/component-tags-order": [ "error", { "order": [ "script", "template", "style" ] } ] } } <script> <template> <style>
  6. 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コンポーネントから分離
  7. 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コンポーネントから分離
  8. 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コンポーネントから分離
  9. 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 } } コンポーネントを跨ぐ状態管理
  10. 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’) コンポーネントを跨ぐ状態管理