Skip to content

Instantly share code, notes, and snippets.

@christianalfoni
Last active September 9, 2024 08:03
Show Gist options
  • Save christianalfoni/5f46bccdeba1d098e2eaf8b3ea1c8e7e to your computer and use it in GitHub Desktop.
Save christianalfoni/5f46bccdeba1d098e2eaf8b3ea1c8e7e to your computer and use it in GitHub Desktop.

vue-productivity

Install

Only use @vitejs/plugin-vue-jsx in vite.config.ts.

Add to tsconfig.json

"compilerOptions": {
  "jsx": "preserve",
  "jsxImportSource": "vue-productivity"
}

Fixes the typing of slots (children)

Simple component

import { createComponent } from 'vue-productivity'

function MyComponent() {
  return <h1>Hello World</h1>
}

export default createComponent(MyComponent)

With props

import { createComponent } from 'vue-productivity'

type Props = { count: number }

function MyComponent(props: Props) {
  return <h1>Count {props.count}</h1>
 }

export default createComponent(MyComponent)

With slots

import { createComponent } from 'vue-productivity'

type Props = { slots: string }

function MyComponent(props: Props) {
  return <div>{props.slots}</div>
}

export default createComponent(MyComponent)

Slots is now <MyComponent>Some slots content</MyComponent>, typed correctly, also works with named slots which is an object of named slots

With state

import { createComponent } from 'vue-productivity'

type SetupProps = { initialCount: number }

type State = { count: number }

function Setup(props: SetupProps): State {
  const count = ref(0)
  
  return {
    get count() {
      return count.value
    }
  }
}

type Props = { slots: string }

function MyComponent(state: State, props: Props) {
  return <div>{state.count} {props.slots}</div>
}

export default createComponent(Setup, MyComponent)

Provide

import { createComponent, createProvider } from 'vue-productivity'

type State = {
  count: number
}

const [provide, inject] = createProvider<State>()

export const useCounter = inject

function Setup() {
  const count = ref(0)
  
  return provide({
    get count() {
      return count.value
    }
  })
}

function Todos(state: State) {
  return (
    <div>
      <h4>Count {state.count}</h4>
      <NestedComponent />
    </div>
  )
}

export default createComponent(Setup, Todos)

Any neste Setup or Component can now use the counter:

import { createComponent } from 'vue-productivity'
import { useCounter } from './Counter'

function Setup() {
  const counter = useCounter()
  
  return {}
}

function MyComponent(state: {}) {
  const counter = useCounter()
  
  return <div>{counter.count}</div>
}

export default createComponent(Setup, MyComponent)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment