面向未来的多框架兼容式框架
面向未来指对Web components的支持。
多框架兼容式指基于cue的组件可方便的与当下流行框架(React、Vue等)结合使用。
确切的说,可与任何可操作DOM的框架结合使用,因为cue的组件打包后本质就是一个DOM元素。
基于jsx并且无虚拟DOM,cue注重编译,少量的runtime代码。
solid
- A declarative, efficient, and flexible JavaScript library for building user interfaces.lit
- Lit is a simple library for building fast, lightweight web components.
- 基于jsx
- 无虚拟DOM,无需diff
- runtime less
- 组件支持任意dom框架及Web components
示例代码见examples/count
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<count-box></count-box>
<script src="/src/index.js" type="module"></script>
</body>
</html>
/src/index.js
import { render, defineWebComponents } from "cue";
import App from "./App";
// 渲染组件
render(<App />, document.getElementById("root"));
// 创建Web components
defineWebComponents('count-box', App);
console.log('获取App的DOM节点:', App());
/src/App.js
import { reactive } from "reactive";
import style from './App.css';
const App = () => {
const count = reactive(0);
const increment = () => {
count(count() + 1);
};
const decrement = () => {
count(count() - 1);
};
return (
<>
<style>{style}</style>
<button type="button" onClick={decrement}> - </button>
<span>{count()}</span>
<button type="button" onClick={increment}> + </button>
</>
);
};
export default App;
示例代码见examples/vue
<script setup>
import { getCurrentInstance, onMounted } from 'vue';
import Count from './count.es.js'; // 打包后的count组件
const { ctx } = getCurrentInstance();
onMounted(() => {
const countNode = Count({
onIncrement() {
console.log('Vue component increment');
},
onDecrement() {
console.log('Vue component decrement');
}
});
ctx.$el.appendChild(countNode);
});
</script>
<template>
<div></div>
</template>
示例代码见examples/react
import React, { useState, useEffect, useRef } from 'react'
import logo from './logo.svg'
import './App.css'
import Count from './count.es.js' // 打包后的count组件
function useCueComponent(CueComponent) {
const container = useRef(null)
useEffect(() => {
container.current.appendChild(CueComponent())
})
return container
}
function App() {
const [count, setCount] = useState(0)
const countContainer = useCueComponent(Count)
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>Hello Vite + React!</p>
<p>
<button type="button" onClick={() => setCount((count) => count + 1)}>
count is: {count}
</button>
</p>
<p>
Edit <code>App.jsx</code> and save to test HMR updates.
</p>
<p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
{' | '}
<a
className="App-link"
href="https://vitejs.dev/guide/features.html"
target="_blank"
rel="noopener noreferrer"
>
Vite Docs
</a>
</p>
<div ref={countContainer}></div>
</header>
</div>
)
}
export default App
1.环境基于nodejs v14.17.5
2.包管理工具使用pnpm
3.采用monorepo管理项目
4.packages/
- babel-plugin-jsx-cue // babel的插件,用来将jsx组件编译为原生dom操作代码
- babel-preset-cue // babel的预设,内置了babel-plugin-jsx-cue插件
- compile-explorer // 代码在线编译浏览
- cue // cue的runtime代码
- reactive // 数据响应式
- vite-plugin-cue // cue的vite插件
- JSX
- 事件绑定
- 组件化
- props
- 控制流
- 生命周期
- Web components
- SSR
- 动画
- computed
- insert types
Thanks goes to these wonderful people (emoji key):
Double Han 📝 💻 |
This project follows the all-contributors specification. Contributions of any kind welcome!