Open9

Vue の Composition API の基本機能をまとめる

setup

  • Composition API は Vue のコア機能を独立した関数として公開するAPIである。
  • setup() 関数はコンポーネントが作られる前に実行される
  • setup()関数は2つの引数を受け取る
    • props: 親コンポーネントから渡されるデータ
    • context: 公開される 3つのプロパティ。attributes, slots, emit events。
<script>
  export default {
    name: "MyComponent",
    setup(props, context) {
    // allow us to access props and context
    },
  };
</script>

setup()関数の最後で template からアクセスするオブジェクトを返す。

<template>
  <h2>{{ getGreeting }}</h2>
  <p>This is the Hello World component.</p>
</template>

<script>
export default {
  name: 'MyComponent',
  setup() {
    return {
      getGreeting: 'Hello World'
    }
  }
}
</script>

ref()

  • data() の代わりになるもの
  • ref()はプリミティブな値を受け取り、reactive で可変なオブkジェクトを返す
  • setup()で return された ref オブジェクトは template からアクセスできる

Nuxt で使ってみる。

components/MyComponent1.vue
<template>
  <div>
    <h2>{{ getGreeting }}</h2>
    <p>This is the Hello World component.</p>
  </div>

</template>

<script>
import { ref } from '@nuxtjs/composition-api'

export default {
  name: 'MyComponent1',
  setup() {
    const getGreeting = ref('Hello World')
    return {
      getGreeting: 'Hello World'
    }
  }
}
</script>
pages/sample.vue
<template>
  <div>
    <MyComponent1 />
  </div>
</template>

<script lang="ts">
import { defineComponent } from "@nuxtjs/composition-api";
import MyComponent1 from "~/components/MyComponent1.vue"

export default defineComponent({
  components: {
    MyComponent1
  },
  setup() {},
});
</script>

ref()

setup() 内で ref オブジェクトにアクセスするときは .value プロパティを利用する。

components/MyComponent1.vue
<template>
  <div>
    <h2>{{ getGreeting }}</h2>
    <p>This is the Hello World component.</p>
  </div>

</template>

<script>
import { ref } from '@nuxtjs/composition-api'

export default {
  name: 'MyComponent1',
  setup() {
    const getGreeting = ref('Hello World')

    console.log('getGreeting: ',getGreeting.value)
    return {
      getGreeting: 'Hello World'
    }
  }
}
</script>

methods() プロパティは使わない

options API ではmethods()プロパティを使っていたが、 Compostion API では必要ない。
JavaScript のメソッドを定義する。

setup()内で定義したメソッドを return すれば template で使えるようになる。

components/MyComponent1.vue
<template>
  <div>
    <h2>{{ getGreeting }}</h2>
    <p>This is the Hello World component.</p>
    <button @click="updateGreeting">Update greeting!</button>
  </div>

</template>

<script>
import { ref } from '@nuxtjs/composition-api'

export default {
  name: 'MyComponent1',
  setup() {
    const getGreeting = ref('Hello World')

    console.log('getGreeting: ',getGreeting.value)

    const updateGreeting = () => {
      return (getGreeting.value = 'Welcome to the app!')
    }
    return {
      getGreeting,
      updateGreeting,
    }
  }
}
</script>

reactive()

  • .value なしでプロパティを更新できる
components/MyComponents2.vue
<template>
  <div>
    <h2>{{ greeting.message }}</h2>
    <p>{{ greeting.description }}</p>
    <button @click="updateGreeting">Update Greeting</button>
  </div>
</template>

<script>
import { reactive } from '@nuxtjs/composition-api'

export default {
  name: 'MyComponent2',
  setup() {
    const greeting = reactive({
      message: 'Hello World',
      description: 'Welcome to the app!'
    })

    const updateGreeting = () => {
      greeting.message = 'Hello Hello';
      greeting.description = 'welcome welcome'
    }

    return {
      greeting,
      updateGreeting
    }
  }
}
</script>

ref() と reactive() の違い

  1. ref() はプリミティブな値をリアクティブにするために使う。 reactive() は JavaScript のオブジェクトをリアクティブにするために使う
  2. reactive()で作られたオブジェクトは再構築したりスプレッド構文で展開したりはできない

JSのスプレッド構文を理解する

reactive()関数を使いつつ、オブジェクトを再構築したいときはtoRefs()関数を使う。
toRefs()でリアクティブ化されたプロパティの値にアクセスするには.valueを使う。

components/MyComponent2.vue
<template>
  <div>
    <h2>{{ message }}</h2>
    <p>{{ description }}</p>
    <button @click="updateGreeting">Update Greeting</button>
  </div>
</template>

<script>
import { reactive, toRefs } from '@nuxtjs/composition-api'

export default {
  name: 'MyComponent2',
  setup() {
    const greeting = reactive({
      message: 'Hello World',
      description: 'Welcome to the app!'
    })

    const greetingRefs = toRefs(greeting)

    const { message, description } = greetingRefs

    const updateGreeting = () => {
      message.value = 'Hello Hello';
      description.value = 'welcome welcome'
    }

    return {
      ...greetingRefs,
      updateGreeting
    }
  }
}
</script>

computed()

computed()をimport して使う。

<template>
  <div>
    <h2>{{ getReversedGreeting }}</h2>
    <p> This is hello world component </p>
  </div>
</template>

<script>
import { ref, computed } from '@nuxtjs/composition-api'

export default {
  name: 'MyComponent3',
  setup() {
    const greeting = ref('Hello World!')

    const getReversedGreeting = computed(() => {
      return greeting.value.split("").reverse().join("")
    })

    return {
      getReversedGreeting
    }
  }
}
</script>

Lifecycle Hooks

import { onMounted, onUpdated, onUnmounted } from 'vue'

onMounted(() => console.log("Component mounted!"));
  • onMounted
  • onUpdated
  • onUnmounted
  • beforeUnmount
  • renderTracked

色々あるので詳細は公式チュートリアルを参照する。

Lifecycle Hooks

Composable functions

  • composition API はコンポーネント間でロジックを使い回せる
  • ロジックを切り離して別ファイルで定義できる
  • ロジックとなる関数をコンポーネントの外に定義できる
composables/useNotification.ts
import { reactive } from '@nuxtjs/composition-api'

const data = reactive({
  message: "",
  active: false,
})

const useNotification = () => {
  const setNotification = (newMessage: string) => {
    data.message = newMessage
    return (data.active = true)
  }

  return {
    notification: data,
    setNotification
  }
}

export default useNotification

コンポーネント:

components/MyComponent4.vue
<template>
  <div>
    {{notification.message}}
  </div>
</template>
<script lang="ts">
import { onMounted } from '@nuxtjs/composition-api'
import useNotification from '@/composables/useNotification'

export default {
  name: 'MyComponent4',
  setup() {
    const { notification, setNotification } = useNotification()

    onMounted(() => {
      setNotification('Component has mounted!')
    })
    return {
      notification
    }
  }
}
</script>

ログインするとコメントできます