React Vue pure JS, Angular Preact…
Different UI libraries have their own state management ecology and are not yet accessible to each other. Switching the technology stack of the UI library means you have to switch the app development ecosystem behind it all, so you have React engineers and Vue engineers on the front end.
In my previous post, I joked about React’s poor state management ecosystem. I thought Vue was just a Vuex, but now I’ve seen a new partner, the ecosystem behind the massive UI library, who are happy to reproduce the state management wheels.
This has led to the formation of a technology stack island in many enterprises, and it is not only a waste of time, but also a waste of life to recruit people based on their RESEARCH and development background. Our company is just one of the victims, backbone Vue React with a long history, every time the switch is a big fight.
In order not to be constrained by such ecological barriers between different technology stacks, we have been looking for a solution that can span the UI library, not only support it, but also allow different UI libraries to coexist in harmony.
This scheme needs to be satisfied
-
The API supports different UI libraries, including backbone vue React Angular…
-
The application can integrate pages and components developed by different UI libraries and coexist harmoniously
Thanks to the inspiration of my colleagues in writing the service, we first came up with rx.js, a popular library on the front end.
However, after a lot of trial and error, we have written rdeco based on rx.js, which I believe will be a great and popular library.
Let’s look at the code to see how RDECo gets through and supports all the UI libraries.
Since our technology stack is mainly React, we wrote a package for rDECo that is easier to integrate with React. In the examples below, you may find the React example more comfortable, but this has nothing to do with RDECo.
Write a pure JS component in RDECo
import { create, inject } from 'rdeco';
create({
name: '@pure/js-com'.state: {
message: 'hello world',},service: {
template() {
return `<div>The ${this.state.message}</div>`; }},exports: {
render([el]) {
el.innerHTML = this.service.template(); ,}}}); inject('@pure/js-com').render(document.getElementById('pure'))
Copy the code
This is a typical example of a component based on pure DOM manipulation, and when the code runs you will see a Hello World rendered on the page
What’s different about writing a React component with rdeco
Write a React component in rdeco
import React from 'react';
import ReactDOM from 'react-dom';
import { createComponent } from 'rdeco';
const Button = createComponent({
name: '@react/button'.state: {
message: 'hello world',},view: {
render() {
return <div type="button">{message}</div>; ,}}}); ReactDOM.render(Button,document.getElementById('react'));
Copy the code
To avoid manually synchronizing the React component’s state, we wrote a createComponent API that maps rdeco states to React.
The result of this example is the same as the above example.
Then there is VUE. Since VUE is bidirectional binding, synchronizing the state is much easier. We didn’t write extra apis to simplify this, but you can implement a Rdeco-Vue yourself if you are interested
Write a Vue component in RDECo
import { createApp } from 'vue';
import { create } from 'rdeco';
create({
name: '@vue/counter'.state: {
counter: vm.counter,
},
ref: {
vm: createApp({
data() {
return {
counter: 0}; }})},exports: {
add() {
vm.counter += 1;
this.setter.counter(vm.counter);
},
render([el]) {
createApp(this.ref.vm).mount(el); ,}}});Copy the code
Ok, the above examples show rDECo as the basic function of state management, state storage, the following is to show how RDECo to achieve the most core ability of state management, state transfer
Since state transfer can be implemented across different UI libraries, it is the same within a single UI library. So the following example shows how rdeco establishes state transfer and control between pure JS components, React components, and Vue components.
State transfer across the UI
Let’s write a simple requirement to describe this example
React implements a Button, Vue implements a Counter, ReactButton changes the VueCounter, and passes the changes to pure JS components for display.
import React from 'react';
import { createComponent, create } from 'rdeco';
import { createApp } from 'vue';
createComponent({
name: '@react/button'.controller: {
onClick() {
inject('@vue/counter').add(); }},view: {
render() {
return (
<button type="button" onClick={this.controller.onClick}>
Click add Counter
</button>); ,}}}); create({name: '@vue/counter'.state: {
counter: vm.counter,
},
ref: {
vm: createApp({
data() {
return {
counter: 0}; }})},exports: {
add() {
vm.counter += 1;
this.setter.counter(vm.counter);
},
render([el]) {
createApp(this.ref.vm).mount(el); ,}}}); create({name: '@puer/message'.subscribe: {
'@vue/counter': {
state: {
counter({ nextState }) {
this.setter.message(nextState); }},}},state: {
message: null,},service: {
template() {
return `<div>The ${this.state.message}</div>`; }},exports: {
render([el]) {
el.innerHTML = this.service.template(); ,}}});Copy the code
The full working example is here: codesandbox.io/s/goofy-kap…
Closing convention, if you are interested in our work, you can follow rDECo: github.com/kinop112365…
Welcome to join us in promoting uniform standards for application r&d at the business level 😁