3
votes

Is it possible to import and use the new Composition API in a traditional component which use the Options API?

This is my scenario:

// ComponentA.js
import { reactive } from '@vue/composition-api'

export default {
  
  ////////////////////////////////////////////////////////////////
  setup() {

    //////////////////////////////////////////////
    // State
    const state = reactive({ 
      isSearching: false,
      searchText: '',
      isShowMoreResults: false,
      resultItems: [] 
    })

    //////////////////////////////////////////////
    const search = async (searchText) => {
      console.log("Searching... ", searchText)
    }

    //////////////////////////////////////////////
    const clear = async () => {
      console.log("Clear search")
    }

    //////////////////////////////////////////////
    const nextResults = async () => {
      console.log("Next Results")
    }

    ////////////////////////////////////////////////////////////////
    return {
      state,
      search,
      clear,
      nextResults
    }
  }
}

I want to use it in my "Options API" style component. How can i import this?

I tried with this but it does not working. The import works fine but i don't know how to call the setup method and get all the exported fields:

import useComponentA from 'ComponentA.js'

let { state } = useComponentA()
1

1 Answers

2
votes

What you have written as your ComponentA.js is the component itself. You returned state, which will become $data.state, and your 3 functions search, clear, and nextResults, which will be methods on the component. If you want to use ComponentA now, you just import it into some ComponentB which uses ComponentA like so

// ComponentB
import ComponentA from 'ComponentA.js'

export default {
  components: { ComponentA },
  // ...
}

If you were to write your ComponentA using the Options API alone, it would look like this:

export default {
  data() {
    return {
      isSearching: false,
      searchText: '',
      isShowMoreResults: false,
      resultItems: [] 
    };
  },
  methods: {
    async search() {...},
    async clear() {...},
    async nextResults() {...}
  }
}

In your example of ComponentA, you aren't really using the Options API at all. You can mix the two APIs like this:

// ComponentA.js
import { reactive } from '@vue/composition-api'

export default {
  setup() {
    const state = reactive({ 
      isSearching: false,
      searchText: '',
      isShowMoreResults: false,
      resultItems: [] 
    })
    return { state }
  },
  methods: {
    async search() {...},
    async clear() {...},
    async nextResults() {...}
  }
}

IMO, you would only mix the APIs if you had some logic that belonged exclusively to the component. For example, if you had some form component and a method for processing the submit event which was unique to that form. It's new enough though, there isn't really a standard convention or best practice.

Update: I've revised my opinion here. After having worked more with Typescript in Vue.js, the Composition API is much more friendly regarding type support for data on the component. The API also facilitates the "collocation" of code "related to the same logical concern." See the Composition API docs for their reasoning. To summarize:

  1. Composition API enables better authoring of components in Typescript
  2. Composition API allows developers to "collocation" code with similar logical concern in complex components (instead of having them sprinkled throughout the component)

Admittedly, point #2 above is less applicable with small, simple components, but if you're using Typescript, #1 is still very applicable.