Nap
Nap
  • 发布:2025-09-17 14:50
  • 更新:2025-09-17 14:50
  • 阅读:59

让UniApp支持React

分类:uni-app

首先dcloud官方花费了巨大的资源保证了全端的api、开发体验保持一致、对于前端开发来说抹平了太多的平台差异,非常之牛逼!!!
uniapp的跨平台能力和生态都非常不错,尤其是在当你需要夸各种平台的时候一套完整的api是多么的珍贵,如果不考虑小程序环境的话那开发起来还是非常顺手的,但是当用uniapp开发小程序的时候,由于小程序环境的限制,太多的特性不能使用,尤其是JSX的能力,这样的话开发起来就束手束脚,很多非常平常的功能,比如说全局的Toast,Modal等等都需要以一个非常受限的方式实现!!!

假设下面这段代码可以直接运行在uniapp中那么开发起来就会无比丝滑

const Sub = (props: any) => {  
      const { children } = props  
      const [value, setValue] = useState(100)  
      useEffect(() => {  
        const timer = setInterval(() => {  
          setValue((value) => {  
            if (value >= 110) {  
              clearInterval(timer)  
            }  
            return value   1  
          })  
        }, 1000)  
        return () => {  
          clearInterval(timer)  
        }  
      }, [])  
      return (  
        <View>  
          sub  
          {value}  
          {value % 2 === 0 ? children : null}  
        </View>  
      )  
    }  
    const Hello = (props: any) => {  
      const [value, setValue] = useState(200)  
      const { unmount } = props  
      const [visible, setVisible] = useState(true)  
      useEffect(() => {  
        if (!visible) {  
          setTimeout(() => {  
            unmount()  
          }, 500)  
        }  
      }, [visible])  
      return (  
        <wd-popup  
          model-value={visible}  
          root-portal={true}  
          position="bottom"  
          onEnter={(event) => {  
            console.log('enter')  
          }}  
          onClose={() => {  
            console.log('close')  
          }}  
        >  
          <Sub a={2}>  
            <View>  
              {true}  
              {false}  
            </View>  
          </Sub>  
          {value % 2 === 0 ? <View>hello react</View> : null}  
          <View>{value}</View>  
          <Button onClick={() => setValue((v) => v   1)}>count  </Button>  
          <Button onClick={() => setValue((v) => v - 1)}>count -</Button>  
          <Button  
            onClick={(event) => {  
              console.log('remove', event)  
              setVisible(false)  
            }}  
          >  
            remove  
          </Button>  
        </wd-popup>  
      )  
    }  

    const id = renderRef.value?.render(  
      <Hello  
        unmount={() => {  
          renderRef.value?.unmount(id)  
        }}  
      />  
    )  

基于这个理由我又造了个轮子,可以让下面的代码运行在各个平台上成了现实,感兴趣的伙伴可以试用下面这个包

安装插件

# 安装插件包  
npm i @js-css/uni-app-react  
# 安装依赖包  
npm i preact @types/react

vite.config.ts 中添加如下配置

import { defineConfig } from 'vite'  
import uni from '@dcloudio/vite-plugin-uni'  
import { UniAppReact } from '@js-css/uni-app-react/dist/plugins/jsx'  
import * as path from 'node:path'  

// https://vitejs.dev/config/  
export default defineConfig({  
  plugins: [  
    // 添加插件  
    UniAppReact(),  
    uni(),  
  ],  
  resolve: {  
    alias: {  
      '@': '/src',  
      // 添加下面四个alias  
      react: path.resolve(__dirname, './node_modules/preact/compat'),  
      'react-is': path.resolve(__dirname, './node_modules/preact/compat'),  
      'react-dom': path.resolve(__dirname, './node_modules/preact/compat'),  
      '@js-css/uni-app-react': path.resolve(  
        __dirname,  
        './node_modules/@js-css/uni-app-react'  
      ),  
    },  
  },  
})

pages.json 中添加一个全局组件 "document": "/document" 该组件由插件自动注入

{  
  "pages": [  
    ...  
  ],  
  "globalStyle": {  
    "navigationBarTextStyle": "black",  
    ...  
    // 添加一个固定的全局组件,该组件由插件自动注入,只需要添加配置即可  
    "usingComponents": {  
      "document": "/document"  
    }  
  }  
}  
0 关注 分享

要回复文章请先登录注册