Skip to content

Instantly share code, notes, and snippets.

@wisetc
Forked from GavinRay97/guide.md
Created March 22, 2021 06:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wisetc/e0696fcb0e10cb92c6ca7733b414116e to your computer and use it in GitHub Desktop.
Save wisetc/e0696fcb0e10cb92c6ca7733b414116e to your computer and use it in GitHub Desktop.
Configuring Nuxt for Composition API and TSX Support

Main

Use create-nuxt-app and enable the Typescript related options to scaffold a new boilerplate TS Nuxt repo:

yarn create nuxt-app <my-project>
# or
npx create-nuxt-app <my-project>

This should install @nuxt/typescript-runtime and @nuxt/typescript-build, plus @nuxt/eslint-config-typescript. Next, run the following:

yarn add nuxt-composition-api
yarn add --dev @nuxt/babel-preset-app babel-preset-vca-jsx@beta vue-tsx-support

vue-tsx-support is the primary provider of TSX functionality, it requires babel-preset-vca-jsx to work properly with the Composition API. @nuxt/babel-preset-app is required as the default base to build off of, so that the other plugin works.

In nuxt.config.(js|ts), import vue-tsx-support/enable-check (you could import it anywhere theoretically, but this seems a good spot) and configure the build.babel property, as well as add nuxt-composition-api to buildModules:

import 'vue-tsx-support/enable-check'
export default {
  // <SNIPPED>
  /*
   ** Nuxt.js dev-modules
   */
  buildModules: [
    '@nuxt/typescript-build',
    'nuxt-composition-api',
  ],

  /*
   ** Build configuration
   ** See https://nuxtjs.org/api/configuration-build/
   */
  build: {
    babel: {
      presets: ['@nuxt/babel-preset-app', 'vca-jsx'],
    },
  },

 // <SNIPPED>
}

Now you should be able to write fully type-checked TSX Components (even mixed in with regular components) using the Composition API =D

import { defineComponent, PropType } from 'nuxt-composition-api'

// This isn't necessary, but can be useful if you want to export and
// strongly type the props being passed from another component
interface MyComponentProps {
  name: string
  age: number
  address: Address
}

interface Address {
  street: string
  zip: number
}

export default defineComponent<MyComponentProps>({
  name: 'MyComponent',
  props: {
    name: String,
    age: Number,
    address: Object as PropType<Address>
  },
  setup: (props) => {
    const { name, age, address } = props
    return () => (
      <div>
        <p>{name}</p>
        <p>{age}</p>
        <p>{address.street}</p>
        <p>{address.zip}</p>
      </div>
    )
  },
})

Adding v-model Support

To add support for v-model, do the following:

yarn add --dev @vue/babel-sugar-v-model

Then, add the plugin to your nuxt-config.(js|ts):

  /*
   ** Build configuration
   ** See https://nuxtjs.org/api/configuration-build/
   */
  build: {
    babel: {
      plugins: ['module:@vue/babel-sugar-v-model'],
      presets: ['@nuxt/babel-preset-app', 'vca-jsx'],
    },
  },

Note the use of module: prefix here, this is because Babel will try to prepend babel-plugin to the package name by default. Now, you can use v-model =)

import { defineComponent, reactive } from 'nuxt-composition-api'

export default defineComponent({
  setup: (props) => {
    const state = reactive({
      text: 'changeme',
    })

    return () => (
      <div>
        <input v-model={state.text} />
        <p>Value {state.text}</p>
      </div>
    )
  },
})
@wisetc
Copy link
Author

wisetc commented Mar 22, 2021

import vue-tsx-support/enable-check.d.ts somewhere

https://github.com/wonderful-panda/vue-tsx-support

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment