:eyes: Vue in React, React in Vue. Seamless integration of the two. :dancers:

Overview

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

Comments
  • Project built with Vue TS component fails

    Project built with Vue TS component fails

    I was using Vuetify components, but recently they updated them to support TS. My build completes, but website breaks with an error: image Project (Vue based) bricks like this while using any component from Vuetify (not a single React component included). I think that Vuera is trying to do something with Vue TS components, because it thinks that it's React component.

    opened by varna 13
  • How to use Vue event handlers in React?

    How to use Vue event handlers in React?

    In Vue, we can use v-on:click directive, and in React it can be onClick. If I want to embed Vue components in React, how can I bind click event to them?

    question 
    opened by e1emeb0t 11
  • [Fix] Component prop updates, issues with children

    [Fix] Component prop updates, issues with children

    Fixes #8.

    I will add tests later. I would be very grateful if you reviewed the changes in src/wrappers/Vue.js and src/wrappers/React.js.

    The changes in React wrapper are pretty straightforward, but the changes in the Vue wrapper are a bit weird and hacky. Please don't hesitate to point out any ways of improvement.

    Also, I would be very grateful for any comments and corrections on the inline documentation in those files. Tell me if some comments need clarification.

    opened by akxcv 10
  • Unknown custom element router-view

    Unknown custom element router-view

    I have Vuera loaded in the same file as my vue router but when I mount vuera it affects vue-router. Here's my router file:

    import Vue from 'vue'
    import Router from 'vue-router'
    import { VuePlugin } from 'vuera'
    import Home from '@/components/Home'
    
    Vue.use(VuePlugin)
    Vue.use(Router)
    
    export default new Router({
      routes: [
        {
          path: '/',
          name: 'Home',
          component: Home
        }
      ]
    })
    

    when I take out the 3rd and 6th line with Vuera/VuePlugin, the app works again. Here's the error I get:

    Unknown custom element: <router-view>
    
    bug help wanted 
    opened by josephrexme 9
  • Add config class

    Add config class

    Redo of https://github.com/akxcv/vuera/pull/90. ea55634 fixes the build bug in https://github.com/akxcv/vuera/pull/90#issuecomment-529439080 - sorry about that!

    Also closes https://github.com/akxcv/vuera/pull/83

    opened by phillbaker 8
  • Error calling React from Vue (

    Error calling React from Vue ("h is not a function")

    I'm having issues calling a React component from a freshly generated Vue project and must be doing something wrong.

    So, starting with vue --version at 2.9.3 (the latest released version) and accepting the defaults in the vue-cli script.

    vue init webpack myapp
    cd myapp
    yarn add vuera react react-dom
    

    Now, I modified the generated /src/main.js entrypoint to import and use the VuePlugin from vuera:

    import Vue from 'vue'
    import App from './App'
    import { VuePlugin } from 'vuera'
    
    Vue.config.productionTip = false
    
    Vue.use(VuePlugin)
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      components: { App },
      template: '<App/>'
    })
    

    Modified the generated App.vue to import and attempt to use the React component:

    <template>
      <div id="app">
        <img src="./assets/logo.png">
        <HelloWorld/>
        <react-component message="Hello"></react-component>
      </div>
    </template>
    
    <script>
    /* eslint-disable */
    import HelloWorld from "./components/HelloWorld";
    import ReactComponent from "./components/ReactComponent";
    
    export default {
      name: "App",
      components: {
        HelloWorld,
        "react-component": ReactComponent
      }
    };
    </script>
    
    <style>
    #app {
      font-family: "Avenir", Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>
    

    Finally added the simple React component /components/ReactComponent.js:

    import React from 'react'
    
    export default class ReactComponent extends React.Component {
      render() {
        return (
          <div>
            <p>This was rendered with React!</p>
            <p>{this.props.message}</p>
          </div>
        )
      }
    }
    

    Webpack compiles everything fine, but when requesting http://localhost:8080 my React component is not rendered under the "Hello World" Vue component. Instead I get 4 errors in the console starting with "Uncaught TypeError: h is not a function".

    screen shot 2018-03-05 at 9 31 07 am

    I also tried using the ReactWrapper but had the same result.

    I'm at the latest vuera 0.2.1, vue 2.5.13, react & react-dom 16.2.0, webpack 3.11.0.

    This library looks to be awesome once it's working, thanks for any help!

    opened by tmepple 8
  • Handle component update

    Handle component update

    Currently, in both React and Vue wrappers, if the component prop is changed, nothing happens.

    Example:

    import RegisteredUser from './RegisteredUser.vue'
    import GuestUser from './GuestUser.vue'
    
    const User = props => {
      const { registered, user } = this.props
      const Component = registered ? RegisteredUser : GuestUser
      return <Component user={user} />
    }
    

    Or, in Vue:

    <template>
      <div>
        <registered-user v-if="registered" :user="user" />
        <guest-user v-else :user="user" />
      </div>
    </template>
    <script>
      import RegisteredUser from './RegisteredUser'
      import GuestUser from './GuestUser'
    
      export default {
        props: ['registered', 'user'],
        components: { RegisteredUser, GuestUser },
      }
    </script>
    

    We expect the component to change from RegisteredUser to GuestUser and back when we change the registered prop, but this does not happen, because both React and Vue wrappers essentially cache the component upon creation.

    This use case is probably not very common, however, this should be handled correctly.

    bug 
    opened by akxcv 8
  • Add config class & Vue instance options

    Add config class & Vue instance options

    This builds off of https://github.com/akxcv/vuera/pull/83 by adding a config object for the options. As well, it adds tests for the usage.

    @akxcv I didn't update the dist/ files, but I can do that if this looks good.

    Would close https://github.com/akxcv/vuera/issues/82.

    opened by phillbaker 7
  • cannot use slate in vue project

    cannot use slate in vue project

    Code as folowing:

    <template>
      <div>
        <Editor :value="value" @change="onChange" />
      </div>
    </template>
    
    <script>
    import { Editor } from 'slate-react'
    import { Value } from 'slate'
    
    const j = {
      document: {
        nodes: [
          {
            object: 'block',
            type: 'paragraph',
            nodes: [
              {
                object: 'text',
                leaves: [
                  {
                    text: 'A line of text in a paragraph.'
                  }
                ]
              }
            ]
          }
        ]
      }
    }
    
    export default {
      name: 'slate',
      components: {
        Editor,
        Value
      },
      data() {
        return {
          value: Value.fromJSON(j)
        }
      },
      methods: {
        onChange(v) {
          console.log('on change:', v)
          this.value = v
        }
      }
    }
    
    </script>
    
    <style>
    
    </style>
    
    

    the editor can display, but cannot edit.

    opened by guotie 7
  • react in vue: SyntheticEvent doesn't work

    react in vue: SyntheticEvent doesn't work

    when i use react component in vue, I try like this, but the test method doesn't work

    react componet

    image

    vue

    image image

    result

    it displays well, but all SyntheticEvent doesn't work, when i click two buttons, the methods don't be triggered image

    opened by yangchendoit 6
  • Fix issue with vuera loading the incorrect component when you have two components registered with the same name

    Fix issue with vuera loading the incorrect component when you have two components registered with the same name

    I faced a bug when I had two different Autocomplete components in my vue application registered under the same name. I traced the bug down to that the newComponentMergeStrategy was loading the incorrect component.

    I think the newComponentsMergeStrategy in vuera should not return the parent merged with the wrappedComponents, it should however return the mergedValue coming from the originalComponentsMergeStrategy merged with the wrappedComponents

    opened by khashish 6
  • Slow rendering of React components.

    Slow rendering of React components.

    I have a VueJS project setup with Nuxt. I have all my Vue pages loading with the SSR support. In one of the main pages, I am rendering React component (Header Component) using Vuera. The react component is at the very top in the component tree, however, the entire page loads first and then React component loads afterwords which is creating confusing behavior for users. Is SSR supported by Vuera or is there any workaround to change priority of rendering so that React component renders first before all Vue components render?

    opened by spatil32 0
  • Bump qs from 6.4.0 to 6.4.1

    Bump qs from 6.4.0 to 6.4.1

    Bumps qs from 6.4.0 to 6.4.1.

    Changelog

    Sourced from qs's changelog.

    6.4.1

    • [Fix] parse: ignore __proto__ keys (#428)
    • [Fix] fix for an impossible situation: when the formatter is called with a non-string value
    • [Fix] use safer-buffer instead of Buffer constructor
    • [Fix] utils.merge: avoid a crash with a null target and an array source
    • [Fix] utils.merge`: avoid a crash with a null target and a truthy non-array source
    • [Fix] stringify: fix a crash with strictNullHandling and a custom filter/serializeDate (#279)
    • [Fix] utils: merge: fix crash when source is a truthy primitive & no options are provided
    • [Fix] when parseArrays is false, properly handle keys ending in []
    • [Robustness] stringify: avoid relying on a global undefined (#427)
    • [Refactor] use cached Array.isArray
    • [Refactor] stringify: Avoid arr = arr.concat(...), push to the existing instance (#269)
    • [readme] remove travis badge; add github actions/codecov badges; update URLs
    • [Docs] Clarify the need for "arrayLimit" option
    • [meta] fix README.md (#399)
    • [meta] Clean up license text so it’s properly detected as BSD-3-Clause
    • [meta] add FUNDING.yml
    • [actions] backport actions from main
    • [Tests] remove nonexistent tape option
    • [Dev Deps] backport from main
    Commits
    • 486aa46 v6.4.1
    • 727ef5d [Fix] parse: ignore __proto__ keys (#428)
    • cd1874e [Robustness] stringify: avoid relying on a global undefined (#427)
    • 45e987c [readme] remove travis badge; add github actions/codecov badges; update URLs
    • 90a3bce [meta] fix README.md (#399)
    • 9566d25 [Fix] fix for an impossible situation: when the formatter is called with a no...
    • 74227ef Clean up license text so it’s properly detected as BSD-3-Clause
    • 35dfb22 [actions] backport actions from main
    • 7d4670f [Dev Deps] backport from main
    • 0485440 [Fix] use safer-buffer instead of Buffer constructor
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Don't pass `children` to React component if not present

    Don't pass `children` to React component if not present

    Consider this React component called in a Vue template:

    <hello-from-react />
    

    Couldn't be simpler. But it passes children which aren't there at all. Using forbidExtraProps from airbnb-prop-types it fails prop-type validation.

    Please ONLY pass children if a component has content, a <slot>, or an explicit children prop.

    Same problem occurs in that other superfluous prop.

    opened by thany 0
  • React component (in Vue app) is receiving a `fragment` prop

    React component (in Vue app) is receiving a `fragment` prop

    Why is this being done?

    In Vue:

    <template>
      <fragment>
        <p>Hello from Vue</p>
    
        <hello-from-react foo="bar" />
      </fragment>
    </template>
    

    In React:

    interface Props {
      foo: string;
    }
    
    const HelloFromReact = (props: Props) => {
      console.log(props); //<-- This proves the passing of a `fragment` prop that is unexpected; `foo` is also there which is okay.
      return <p>Hello from React typescript</p>;
    };
    
    export default HelloFromReact;
    

    This will break strict props validation that we will be adding in the future. Can vuera please ONLY pass props that are being specified in the template that calls the React component?

    opened by thany 0
  • feat: support hyphenation attribute for React in Vue

    feat: support hyphenation attribute for React in Vue

    Issue #40

    Now you can use hyphenation attributes for React components in Vue, thus it won't break standard Vue lint rules.

    <template>
        // works now 🎉
        <react-component :hyphenation-attr="nice" />
    </template>
    
    opened by pureliumy 0
Releases(0.2.5)
Owner
Aleksandr Komarov
Aleksandr Komarov
Morse code is a method used in telecommunication to encode text characters as standardized sequences of two different signal durations, called dots and dashes, or dits and dahs.

@elonehoo/point-line Install # npm npm i @elonehoo/point-line # yarn yarn add @elonehoo/point-line #pnpm pnpm i @elonehoo/point-line Usage import {dec

Elone Hoo 5 Aug 3, 2022
Batteries-included, zero-config Ionic integration for Nuxt

Nuxt Ionic Ionic integration for Nuxt ✨ Changelog ?? Read the documentation ▶️ Online playground Features ⚠️ nuxt-ionic is currently a work in progres

Daniel Roe 211 Dec 28, 2022
OpenID-Connect(OIDC) integration module for nuxt 3.0.

Nuxt OpenID-Connect OpenID-Connect(OIDC) integration module for nuxt 3.0. Features An Nuxt 3 module. OIDC integration ( implemetation base openid-clie

Aborn Jiang 10 Dec 24, 2022
✉️ Nuxt module for first class integration with popular newsletter providers

nuxt-newsletter Newsletter module for Nuxt 3 ✨ Release Notes ?? Read the documentation Features Nuxt 3 ready Easy integration with Mailchimp, Revue, B

Jakub Andrzejewski 39 Jan 5, 2023
[WIP] Firebase Integration for Nuxt(3)

Nuxt Firebase Integrate Firebase with Nuxt (3) This module is not ready for production use. Install # npm npm install -D firebase @e-chan1007/nuxt-fir

e-chan1007 5 Dec 8, 2022
:tada: A magical vue admin https://panjiachen.github.io/vue-element-admin

English | 简体中文 | 日本語 | Spanish SPONSORED BY 活动服务销售平台 客户消息直达工作群 Introduction vue-element-admin is a production-ready front-end solution for admin inter

花裤衩 80.1k Dec 31, 2022
🎉 基于 vite 2.0 + vue 3.0 + vue-router 4.0 + vuex 4.0 + element-plus 的后台管理系统vue3-element-admin

vue3-element-admin ?? 基于 Vite 2.0 + Vue3.0 + Vue-Router 4.0 + Vuex 4.0 + element-plus 的后台管理系统 简介 vue3-element-admin 是一个后台前端解决方案,它基于 vue3 和 element-plu

雪月欧巴 84 Nov 28, 2022
Jenesius vue modal is simple library for Vue 3 only

Jenesius Vue Modal Jenesius vue modal is simple library for Vue 3 only . Site Documentation Installation npm i jenesius-vue-modal For add modals in yo

Архипцев Евгений 63 Dec 30, 2022
A template repository / quick start to build Azure Static Web Apps with a Node.js function. It uses Vue.js v3, Vue Router, Vuex, and Vite.js.

Azure Static Web App Template with Node.js API This is a template repository for creating Azure Static Web Apps that comes pre-configured with: Vue.js

Marc Duiker 6 Jun 25, 2022
Mosha-vue-toastify - A light weight and fun Vue 3 toast or notification or snack bar or however you wanna call it library.

Mosha Vue Toastify A lightweight and fun Vue 3 toast or notification or snack bar or however you wanna call it library. English | 简体中文 Talk is cheap,

Baidi Liu 187 Jan 2, 2023
A plugin that can help you create project friendly with Vue for @vue/cli 4.5

vue-cli-plugin-patch A plugin that can help you create project friendly with Vue for @vue/cli 4.5. Install First you need to install @vue/cli globally

null 2 Jan 6, 2022
Veloce: Starter template that uses Vue 3, Vite, TypeScript, SSR, Pinia, Vue Router, Express and Docker

Veloce Lightning-fast cold server start Instant hot module replacement (HMR) and dev SSR True on-demand compilation Tech Stack Vue 3: UI Rendering lib

Alan Morel 10 Oct 7, 2022
📓 The UI component explorer. Develop, document, & test React, Vue, Angular, Web Components, Ember, Svelte & more!

Build bulletproof UI components faster Storybook is a development environment for UI components. It allows you to browse a component library, view the

Storybook 75.9k Jan 9, 2023
NativeScript empowers you to access native api's from JavaScript directly. Angular, Vue, Svelte, React and you name it compatible.

NativeScript empowers you to access native APIs from JavaScript directly. The framework currently provides iOS and Android runtimes for rich mobile de

NativeScript 22k Jan 4, 2023
JavaScript data grid with a spreadsheet look & feel. Works for React, Angular, and Vue. Supported by the Handsontable team ⚡

Handsontable is a JavaScript component that combines data grid features with spreadsheet-like UX. It provides data binding, data validation, filtering

Handsontable 17.4k Dec 31, 2022
Mobile app development framework and SDK using HTML5 and JavaScript. Create beautiful and performant cross-platform mobile apps. Based on Web Components, and provides bindings for Angular 1, 2, React and Vue.js.

Onsen UI - Cross-Platform Hybrid App and PWA Framework Onsen UI is an open source framework that makes it easy to create native-feeling Progressive We

null 8.7k Jan 4, 2023
Created from react styleguidist for Vue Components with a living style guide

Isolated Vue component development environment with a living style guide Start documenting now on codesandbox.io Sponsors A big thank you to our spons

Vue Styleguidist 2.3k Dec 28, 2022
Matteo Bruni 4.7k Jan 4, 2023
The first truly composable CSS animation library. Built for Vue, React, SCSS, and CSS, AnimXYZ will bring your website to life.

AnimXYZ animxyz.com AnimXYZ helps you create, customize, and compose animations for your website. Powered by CSS variables to allow a nearly limitless

Ingram Projects 2.1k Jan 2, 2023