标签 Composition API 下的文章

前端开发者常常面临这样的困境:Vue项目需要使用React生态的优秀组件,或者React项目想引入Vue的优雅解决方案。过去,这几乎意味着需要完全重写或寻找笨重的替代方案。

今天介绍的Veaury将彻底改变这一局面。这是一个专门设计用于在Vue和React之间实现无缝互操作的工具库。

核心问题与挑战

在实际开发中,跨框架组件复用面临诸多挑战:

  1. 上下文隔离:Vue和React有各自独立的上下文系统,数据传递困难
  2. 生命周期不匹配:两个框架的生命周期模型完全不同
  3. 事件系统差异:Vue使用自定义事件,React使用合成事件
  4. 渲染机制不同:Vue基于模板,React基于JSX

Veaury的技术实现原理

Veaury通过高阶组件(HOC)的方式,在两种框架之间搭建桥梁。其核心思路是:

// 简化版实现原理示意
function createCrossFrameworkWrapper(OriginalComponent, targetFramework) {
  return function Wrapper(props, context) {
    // 处理props转换
    const convertedProps = convertProps(props, targetFramework);
    
    // 处理上下文传递
    const frameworkContext = adaptContext(context, targetFramework);
    
    // 根据目标框架选择渲染方式
    if (targetFramework === 'vue') {
      return renderAsVue(OriginalComponent, convertedProps, frameworkContext);
    } else {
      return renderAsReact(OriginalComponent, convertedProps, frameworkContext);
    }
  };
}

主要特性

1. 完整的Vue 3支持

  • 支持Composition API和Options API
  • 支持Teleport、Suspense等Vue 3特性
  • 完整的响应式系统集成

2. 双向上下文共享

// React组件可以访问Vue的provide/inject
// Vue组件可以访问React的Context
const SharedComponent = ({ theme }) => {
  // theme可以来自Vue的provide或React的Context
  return <div className={`theme-${theme}`}>共享主题</div>;
};

3. 纯模式(Pure Mode)

消除包装器带来的额外DOM元素,保持组件树的整洁:

// 使用纯模式包装
const PureReactComponent = applyPureReactInVue(ReactComponent);
// 渲染结果没有额外的div包裹

4. 生命周期映射

Veaury智能地映射两个框架的生命周期:

Vue 生命周期React 等效
onMounteduseEffect(() => {}, [])
onUpdateduseEffect(() => {})
onUnmounteduseEffect(() => () => {})

实际应用示例

场景一:在Vue项目中使用React组件

<template>
  <div>
    <h2>Vue组件主体</h2>
    <!-- 直接使用React组件 -->
    <ReactDataTable :data="tableData" @row-click="handleRowClick" />
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { applyPureReactInVue } from 'veaury';
import ReactDataTable from './ReactDataTable.jsx';

// 将React组件转换为Vue可用的组件
const ReactDataTable = applyPureReactInVue(ReactDataTable);

const tableData = ref([
  { id: 1, name: '项目A', value: 100 },
  { id: 2, name: '项目B', value: 200 }
]);

const handleRowClick = (rowData) => {
  console.log('行点击事件:', rowData);
  // 处理来自React组件的事件
};
</script>

场景二:在React项目中使用Vue组件

import React, { useState } from 'react';
import { applyVueInReact } from 'veaury';
import VueRichEditor from './VueRichEditor.vue';

const RichEditor = applyVueInReact(VueRichEditor);

function App() {
  const [content, setContent] = useState('');
  const [isDarkMode, setIsDarkMode] = useState(false);

  const handleContentChange = (newContent) => {
    setContent(newContent);
    // 处理来自Vue组件的事件
  };

  return (
    <div className={isDarkMode ? 'dark-theme' : 'light-theme'}>
      <h1>React应用中的Vue富文本编辑器</h1>
      <RichEditor
        modelValue={content}
        onUpdate:modelValue={handleContentChange}
        darkMode={isDarkMode}
        v-slots={{
          toolbar: () => <div>自定义工具栏</div>
        }}
      />
      <button onClick={() => setIsDarkMode(!isDarkMode)}>
        切换主题
      </button>
    </div>
  );
}

性能考虑

Veaury在性能方面做了大量优化:

  1. 最小化重渲染:通过精细的响应式侦听,避免不必要的重新渲染
  2. 内存效率:合理管理组件实例,避免内存泄漏
  3. 构建优化:支持Tree-shaking,只引入需要的功能

性能对比示例:

// 传统iframe方案 vs Veaury方案
// iframe:独立的DOM、样式和上下文,开销大
// Veaury:共享同一DOM,轻量级包装,性能接近原生

企业级应用实践

案例:低代码平台集成

某低代码平台使用Veaury实现插件系统:

  • 核心框架:Vue 3 + TypeScript
  • 插件生态:支持React和Vue两种插件
  • 实现效果:开发者可使用任意框架开发插件

案例:微前端架构

在微前端场景中,Veaury帮助不同技术栈的子应用共享组件:

// 主应用(Vue)使用子应用(React)的组件库
import { applyPureReactInVue } from 'veaury';
import ReactDesignSystem from 'team-react-ds';

// 在Vue主应用中直接使用React设计系统
const VueWrappedButton = applyPureReactInVue(ReactDesignSystem.Button);
const VueWrappedModal = applyPureReactInVue(ReactDesignSystem.Modal);

配置与构建

Vite配置示例

// vite.config.js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import veauryVitePlugins from 'veaury/vite';

export default defineConfig({
  plugins: [
    veauryVitePlugins({
      type: 'vue', // 或 'react',根据主框架选择
      vueOptions: {
        reactivityTransform: true // 启用响应式语法糖
      }
    })
  ],
  optimizeDeps: {
    include: ['veaury']
  }
});

Webpack配置要点

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.vue$/,
        use: 'vue-loader'
      },
      {
        test: /\.jsx$/,
        use: 'babel-loader',
        options: {
          presets: ['@babel/preset-react']
        }
      }
    ]
  }
};

局限性说明

尽管Veaury功能强大,但仍有一些限制:

  1. 部分高级特性:某些框架特定的高级特性可能不完全支持
  2. 开发体验:调试时需要了解两种框架
  3. 学习成本:团队需要同时熟悉Vue和React

总结

对于需要在Vue和React之间搭建桥梁的项目,Veaury提供了一个成熟、稳定的解决方案。无论是新项目技术选型,还是老项目现代化改造,都值得考虑这一工具。

技术栈不应成为创新的约束,而应是实现目标的工具。 Veaury正是这一理念的实践,让开发者能够专注于创造价值,而不是被框架之争所困扰。

本文由mdnice多平台发布

Vue3 核心知识点读书笔记

一、Vue 核心原理与架构

1. MVVM 核心模式(核心架构)

Vue 基于 MVVM 模式设计,核心是实现视图与数据的解耦,三者关系如下:

模块核心职责
Model数据层,负责业务数据处理(纯数据,无视图交互逻辑)
View视图层,即用户界面(仅展示内容,不处理数据逻辑)
ViewModel桥梁层,连接 View 和 Model,包含两个核心能力:
✅ DOM Listeners:监听 View 中 DOM 变化,同步到 Model
✅ Data Bindings:监听 Model 中数据变化,同步到 View
关键:View 和 Model 不能直接通信,必须通过 ViewModel 中转,实现解耦。

2. Vue 核心特性(四大核心)

特性具体说明示例/应用场景
数据驱动视图数据变化自动触发视图重新渲染,无需手动操作 DOM修改变量值 → 页面自动更新
双向数据绑定视图变化 ↔ 数据变化双向同步表单输入框内容自动同步到数据变量
指令分内置指令(Vue 自带)和自定义指令,以v-开头绑定到 DOM 元素v-bind(单向绑定)、v-if(条件渲染)、v-for(列表渲染)
插件支持扩展功能,配置简单VueRouter(路由)、Pinia(状态管理)

二、Vue 版本与开发环境

1. Vue2 vs Vue3 核心差异

维度Vue3 变化
新增功能组合式(Composition)API、多根节点组件、底层渲染/响应式逻辑重构(性能提升)
废弃功能过滤器(Filter)、$on()/$off()/$once() 实例方法
兼容性兼容 Vue2 绝大多数 API,新项目推荐直接使用 Vue3

2. 开发环境准备(必装)

  1. 编辑器:VSCode → 安装「Vue (Official)」扩展(提供代码高亮、语法提示)
  2. 运行环境:Node.js(官网下载安装,为包管理工具提供基础)
  3. 包管理工具:npm/yarn(管理第三方依赖,支持一键安装/升级/卸载,避免手动下载解压)

三、Vite 创建 Vue3 项目(核心操作)

1. 项目创建命令(适配 npm10 版本)

# Yarn 方式(推荐)
yarn create vite hello-vite --template vue

# 交互提示处理(关键步骤,不要遗漏):
# 1. 提示 "Use rolldown-vite (Experimental)?" → 回车选 No(优先使用稳定版)
# 2. 提示 "Install with yarn and start now?" → 回车选 Yes(自动安装依赖并启动项目)

2. 手动创建命令(补充)

# npm 方式
npm create vite@latest
# yarn 方式
yarn create vite
# 后续需手动填写项目名称、选择框架(Vue)、选择变体(JavaScript)

四、Vue3 项目核心文件与目录

1. 项目目录结构(重点关注)

hello-vite/          # 项目根目录
├── node_modules/    # 第三方依赖包(自动生成)
├── dist/            # 构建产物(执行 yarn build 后生成,用于部署)
├── src/             # 源代码目录(开发核心)
│   ├── assets/      # 静态资源(图片、样式等)
│   ├── components/  # 自定义组件
│   ├── App.vue      # 根组件
│   ├── main.js      # 项目入口文件
│   └── style.css    # 全局样式
├── index.html       # 页面入口文件
└── package.json     # 项目配置(依赖、脚本命令)

2. 核心文件代码解析(带完整注释)

(1)index.html(页面入口)
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>hello-vite</title>
  </head>
  <body>
    <!-- Vue 实例挂载容器:被 main.js 中的 Vue 实例控制 -->
    <div id="app"></div>
    <!-- type="module":启用 ES6 模块化语法,引入项目入口文件 -->
    <script type="module" src="/src/main.js"></script>
  </body>
</html>
(2)src/main.js(项目入口,创建 Vue 实例)
// 从 Vue 中导入创建应用实例的核心函数
import { createApp } from 'vue'
// 导入全局样式文件
import './style.css'
// 导入根组件(App.vue)
import App from './App.vue'

// 方式1:简洁写法(创建实例 + 挂载到 #app 容器)
createApp(App).mount('#app')

// 方式2:分步写法(更易理解,效果一致)
// const app = createApp(App) // 创建 Vue 应用实例
// app.mount('#app') // 挂载实例(仅可调用一次)
(3)src/App.vue(根组件,单文件组件核心)
<!-- script setup:Vue3 组合式 API 语法糖,简化组件编写 -->
<script setup>
// 导入子组件(HelloWorld.vue)
import HelloWorld from './components/HelloWorld.vue'
</script>

<!-- template:组件模板结构(视图部分) -->
<template>
  <div>
    <a href="https://vite.dev" target="_blank">
      <img src="/vite.svg" class="logo" alt="Vite logo" />
    </a>
    <a href="https://vuejs.org/" target="_blank">
      <img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
    </a>
  </div>
  <!-- 使用子组件,传递 msg 属性 -->
  <HelloWorld msg="Vite + Vue" />
</template>

<!-- style scoped:样式仅作用于当前组件(通过 Hash 隔离,不影响子组件) -->
<style scoped>
.logo {
  height: 6em;
  padding: 1.5em;
  will-change: filter;
  transition: filter 300ms;
}
.logo:hover {
  filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {
  filter: drop-shadow(0 0 2em #42b883aa);
}
</style>

五、核心知识点总结

1. 核心原理

  • Vue 基于 MVVM 模式,通过 ViewModel 实现视图与数据的双向驱动,核心是「数据驱动视图」,无需手动操作 DOM;
  • 双向数据绑定是 Vue 核心特性,表单场景下可自动同步视图与数据。

2. 项目开发

  • Vue3 推荐使用 Vite 创建项目(比 VueCLI 更快),npm10 版本下优先用 yarn create vite 项目名 --template vue 命令;
  • 项目核心文件:index.html(页面入口)→ main.js(创建 Vue 实例)→ App.vue(根组件),三者构成项目基础骨架。

3. 关键注意点

  • mount() 方法仅可调用一次,挂载目标可以是 DOM 元素或 CSS 选择器(#app/.app);
  • <style scoped> 样式仅作用于当前组件,避免样式污染;
  • Vue3 废弃了过滤器、$on/$off/$once 等功能,开发时需避开。