Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

vuera

akxcv16.4kMIT0.2.7

Use React in Vue and Vue in React

vue, react, interop, adapter, migrate, seamless-integration

readme

vuera

Build Status Coverage Status

NOTE: This project is looking for a maintainer!

Use Vue components in your React app:

import React from 'react'
import MyVueComponent from './MyVueComponent.vue'

export default props =>
  <div>
    <MyVueComponent message={props.message} handleReset={props.handleReset} />
  </div>

Or use React components in your Vue app:

<template>
  <div>
    <my-react-component :message="message" @reset="reset" />
  </div>
</template>

<script>
  import MyReactComponent from './MyReactComponent'

  export default {
    /* data, methods, etc */
    components: { 'my-react-component': MyReactComponent },
  }
</script>

Use cases

  • 👨‍👩‍👧 Using both Vue and React in one app
  • 🏃 Migrating from React to Vue or from Vue to React

Installation

Install with yarn:

$ yarn add vuera
# or with npm:
$ npm i -S vuera

You can also try the library out via unpkg:

<script src="https://unpkg.com/vuera"></script>

Usage

Vue in React - Preferred usage

The preferred way to use Vue inside of a React app is to use a Babel plugin.

Add vuera/babel to plugins section of your .babelrc:

{
  "presets": "react",
  "plugins": ["vuera/babel"]
}

Now, just use your Vue components like you would use your React components!

import React from 'react'
import MyVueComponent from './MyVueComponent.vue'

export default () => (
  <div>
    <h1>I'm a react component</h1>
    <div>
      <MyVueComponent message='Hello from Vue!' />
    </div>
  </div>
)

React in Vue - Preferred usage

The preferred way to use React inside of a Vue app is to use a Vue plugin.

import Vue from 'vue'
import { VuePlugin } from 'vuera'

Vue.use(VuePlugin)
/* ... */

Now, use your React components like you would normally use your Vue components!

<template>
  <div>
    <h1>I'm a Vue component</h1>
    <my-react-component :message="message" @reset="reset" />
  </div>
</template>

<script>
  import MyReactComponent from './MyReactComponent'

  export default {
    data () {
      message: 'Hello from React!',
    },
    methods: {
      reset () {
        this.message = ''
      }
    },
    components: { 'my-react-component': MyReactComponent },
  }
</script>

If you configure options in the root instance of a Vue, those will not be passed by default to Vue instances within React components. So, for example an i18n or a store instance option configured at the top level is not available in the children Vue components wrapped in React components. To fix this, configure vueInstanceOptions similar to:

import Vue from 'vue'
// import other plugins or modules
import { config } from 'vuera'

// Vue.use(...)

config.vueInstanceOptions = { plugin: thePlugIn, store: myStore };

NOTE: If you're using Vue < 2.4, you must pass all props to your React components via a special prop called passedProps:

<template>
  <div>
    <h1>I'm a Vue component</h1>
    <my-react-component :passedProps="passedProps"></my-react-component>
  </div>
</template>

<script>
  import { ReactWrapper } from 'vuera'
  import MyReactComponent from './MyReactComponent'

  export default {
    data () {
      message: 'Hello from React!',
    },
    methods: {
      reset () {
        this.message = ''
      }
    },
    computed: {
      passedProps () {
        return {
          message: this.message,
          reset: this.reset,
        }
      },
    },
    components: { 'my-react-component': MyReactComponent },
  }
</script>

Vue in React - without the Babel plugin

If you don't want to use the Babel plugin, you still have two ways of using this library.

  1. Use a wrapper component:
import React from 'react'
import { VueWrapper } from 'vuera'
import MyVueComponent from './MyVueComponent.vue'

export default () => (
  <div>
    <VueWrapper
      component={MyVueComponent}
      message='Hello from Vue!'
    />
  </div>
)
  1. Or use the HOC API:
import React from 'react'
import { VueInReact } from 'vuera'
import MyVueComponent from './MyVueComponent.vue'

export default () => {
  const Component = VueInReact(MyVueComponent)
  return (
    <div>
      <Component message='Hello from Vue!' />
    </div>
  )
}

React in Vue - without the Vue plugin

If you don't want to use the Vue plugin, you still have two ways of using this library.

  1. Use a wrapper component:
<template>
  <div>
    <react :component="component" :message="message" />
  </div>
</template>

<script>
  import { ReactWrapper } from 'vuera'
  import MyReactComponent from './MyReactComponent'

  export default {
    data () {
      component: MyReactComponent,
      message: 'Hello from React!',
    },
    components: { react: ReactWrapper }
  }
</script>
  1. Use the HOC API:
<template>
  <div>
    <my-react-component :message="message" />
  </div>
</template>

<script>
  import { ReactInVue } from 'vuera'
  import MyReactComponent from './MyReactComponent'

  export default {
    data () {
      message: 'Hello from React!',
    },
    components: { 'my-react-component': ReactInVue(MyReactComponent) }
  }
</script>

FAQ (I think)

Are children supported?

Yes. You can pass children from React to Vue and back as you usually would.

React (children will go to the default slot of the Vue component):

import React from 'react'
import MyVueComponent from './MyVueComponent.vue'

export default props =>
  <div>
    <MyVueComponent message={props.message}>
      Hello there!
    </MyVueComponent>
  </div>

Vue:

<template>
  <div>
    <my-react-component :message="message">
      G'day sir
    </my-react-component>
  </div>
</template>

<script>
  import MyReactComponent from './MyReactComponent'

  export default {
    components: { 'my-react-component': MyReactComponent },
  }
</script>

What's the performance? How fast/slow is it compared to pure React / Vue?

I don't know, but the benchmark is coming. Stay tuned.

Articles

Integrating React and Vue Components in One Application by @josephrexme

License

MIT

changelog

Change Log

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog and this project adheres to Semantic Versioning.

[0.2.7] - 2020-01-27

Added

[0.2.6] - 2019-10-15

Fixed

  • Vue components that use Vue.extend (#95) - @wenlz123

[0.2.5] - 2019-04-22

Fixed

  • Incorrect handling of multiple components with same name (#79) - @khashish

    [0.2.4] - 2019-03-20

    Fixed

  • Usage with styled-components (#69) - @fsodano
  • Improved Vue component detection (#71) - @runebaas
  • Builds and tests can now be run on Windows (#73) - @runebaas

[0.2.3] - 2018-10-13

Fixed

  • React 16.5 prop warnings (#62) - @walts81

    Added

  • Support for custom Vue events (#62) - @walts81

[0.2.2] - 2018-06-22

Fixed

  • React component check for native (ES6) arrow functions (#44).

[0.2.1] - 2018-02-14

Fixed

  • Only pass wrapped children if children exist to pass prop type validation. (#27) - @phillbaker

[0.2.0] - 2017-11-10

Updated

  • Rollup 0.51
  • React 16.1
  • Vue 2.5

[0.1.3] - 2017-11-02

Fixed

  • Bug with globally registered Vue components (#18).

[0.1.2] - 2017-10-07

Fixed

  • Issues with component prop updates. (#5)
  • Issues with children in Babel plugin.
  • Issues with children updates.

[0.1.1] - 2017-10-04

Fixed

  • Babel plugin could not be imported as specified in README. (#5)

[0.1.0] - 2017-10-03

Initial release.