🚶‍♂️

Vue Composition API と Vue 3 での実装方法の違いについて

2021/01/07に公開

この記事では、昨年α版がリリースされた Vue3 と、それまで使われ続けた Vue Composition API との実装の違いで個人的に戸惑ってしまったことについてまとめました。

1:Props の 型定義について

Props での型の定義では、それまでは setup() 内で再定義できましたが、Vue 3 ではその方式が廃止されました。

<script>

type SampleType={
  name: string,
  number: number
}

// 以下のProps の型定義は Vue 3 では廃止されている
setup(props: SampleType){
}

</script>

2:setup() の引数について

setup() において、 Vue composition API では、第2引数にはSetupContext型が割り当てられており、Vue Router, Vuex など、setup 関数で必要とする機能を呼び出せました。しかし、Vue 3 からは、使用できる引数が attrs, slots, emit しか使用できません。

もし Vue Router を使用したい場合は useRouter, useRoute関数を Vue Router ライブラリから import する必要があります。

Vue Composition API で URL遷移をする場合

<script>
  // (省略)
  setup(props,{root}){
    const router = context.root.$router
    router.push("/login")
  }
</script>

Vue 3 でURL遷移をする場合

<script>
   // ライブラリより useRouter 関数を呼び出す 
  import {useRouter} from "vue-router" 
  // (省略)
  setup(props){
    const router = useRouter()
    router.push("/login")
  }
</script>

3:子 Component を親 Component で v-model を使って呼び出すとき

Vue 3 では、<input/> Component を分割したものを呼び出すとき、v-model で使用できるようにするには次のように変更されました。

  • prop: value -> modelValue
  • event: input -> update:modelValue と設定します。

(注):2020 年 1月 4日 の段階では まだ breaking状態 で、今後仕様が変わる可能性があります。

参照:https://v3.vuejs.org/guide/migration/v-model.html#overview

子 Component

<template>
  <div>
    <input type ="type" :placeholder="placeholder" :name="name" 
     :value="modelValue" @input="inputHandler">
  </div>
</template>
<script>
  import {defineComponent,ref} from "vue"

  export default defineComponent({
    props:{
      name:{
          type: String,
          required: false,
          default:""
      },
      type:{
          type :String,
          required:false,
          default:"email",
        },
      placeholder : {
          type: String, 
          required: false,
          default: "sample"
        },
      modelValue:{
          type: [String, Number],
          required : false
          default:"",
      },
    }
    setup(props,{emit}){
      const inputHandler = (e: any)=>{
          emit('update:modelValue',e.target.value)
      }
      return {
          inputHandler
      }
    }
  })
</script>

親 Component


<template>
  <MyComponent v-model="input"/>
</template>
<script>
import {defineComponent,ref} from "vue"
import {MyComponent} from "./mycomponent.vue";

export default defineComponent({
  components:{MyComponent},
  setup(){
    const input =ref("");
    return {
      input
    }
  }
})
</script>

参考文献

Discussion