Integrate in Vue

If you are looking for how to use Vue components as custom components, please refer to here.

Before integrating Univer into an Vue project, read installation and basic usage and familiarize yourself with Vue components and lifecycle hooks.

Vue 3.x

Notes before integration

  • Avoid proxying the Univer and FUniver instances, as this may lead to unpredictable errors or performance issues.

Integration Steps

  1. Initialize Univer in the onMounted hook
  2. Destroy Univer in the onBeforeUnmount hook

Example

Vue
<script lang="ts" setup>import type { Univer } from '@univerjs/presets'import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US'import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'import { onBeforeUnmount, onMounted, ref } from 'vue'import '@univerjs/preset-sheets-core/lib/index.css'const container = ref<HTMLElement | null>(null)let univerInstance: Univer | null = nullonMounted(() => {  const { univer, univerAPI } = createUniver({    locale: LocaleType.EN_US,    locales: {      [LocaleType.EN_US]: mergeLocales(        UniverPresetSheetsCoreEnUS,      ),    },    presets: [      UniverSheetsCorePreset({        container: container.value as HTMLElement,      }),    ],  })  univerAPI.createWorkbook({})  univerInstance = univer})onBeforeUnmount(() => {  univerInstance?.dispose()  univerInstance = null})</script><template>  <div ref="container" style="height: 600px" /></template>

Vue 2.x

Notes before integration

  • When installing @univerjs/presets with pnpm, you may need to manually install react and react-dom.
  • If you encounter the "ResizeObserver loop limit exceeded" warning in the development environment, you can ignore it or refer to the code snippet below to resolve it:
TypeScript
if (process.env.NODE_ENV === 'development') {  const _ResizeObserver = window.ResizeObserver  function debounce(fn, delay) {    let timer = null    return function () {      if (timer) {        clearTimeout(timer)      }      timer = setTimeout(() => {        fn.apply(this, arguments)      }, delay)    }  }  window.ResizeObserver = class ResizeObserver extends _ResizeObserver {    constructor(callback) {      callback = debounce(callback, 50)      super(callback)    }  }}
  • If using Vue CLI 3.x/4.x (based on Webpack 4.x) as the build tool, you need to manually change the mapped paths to the actual paths:
JavaScript
// vue.config.jsconst path = require('node:path')module.exports = {  transpileDependencies: ['@wendellhu/redi'],  configureWebpack: {    resolve: {      alias: {        '@univerjs/core/facade': path.resolve(__dirname, 'node_modules/@univerjs/core/lib/facade.js'),        '@univerjs/engine-formula/facade': path.resolve(__dirname, 'node_modules/@univerjs/engine-formula/lib/facade.js'),        '@univerjs/preset-sheets-core/lib/index.css': path.resolve(__dirname, 'node_modules/@univerjs/preset-sheets-core/lib/index.css'),        '@univerjs/preset-sheets-core/locales/en-US': path.resolve(__dirname, 'node_modules/@univerjs/preset-sheets-core/lib/es/locales/en-US.js'),        '@univerjs/design/locale/en-US': path.resolve(__dirname, 'node_modules/@univerjs/design/lib/es/locale/en-US.js'),        '@univerjs/docs-ui/locale/en-US': path.resolve(__dirname, 'node_modules/@univerjs/docs-ui/lib/es/locale/en-US.js'),        '@univerjs/sheets-formula-ui/locale/en-US': path.resolve(__dirname, 'node_modules/@univerjs/sheets-formula-ui/lib/es/locale/en-US.js'),        '@univerjs/sheets-formula/locale/en-US': path.resolve(__dirname, 'node_modules/@univerjs/sheets-formula/lib/es/locale/en-US.js'),        '@univerjs/sheets-numfmt-ui/locale/en-US': path.resolve(__dirname, 'node_modules/@univerjs/sheets-numfmt-ui/lib/es/locale/en-US.js'),        '@univerjs/sheets-ui/locale/en-US': path.resolve(__dirname, 'node_modules/@univerjs/sheets-ui/lib/es/locale/en-US.js'),        '@univerjs/sheets/facade': path.resolve(__dirname, 'node_modules/@univerjs/sheets/lib/facade.js'),        '@univerjs/sheets/locale/en-US': path.resolve(__dirname, 'node_modules/@univerjs/sheets/lib/es/locale/en-US.js'),        '@univerjs/ui/locale/en-US': path.resolve(__dirname, 'node_modules/@univerjs/ui/lib/es/locale/en-US.js'),        '@wendellhu/redi/react-bindings': path.resolve(__dirname, 'node_modules/@wendellhu/redi/dist/esm/react-bindings/index.js'),        // ...      },    },  },}

Integration Steps

  1. Initialize Univer in the mounted hook
  2. Destroy Univer in the beforeDestroy hook

Example

Vue
<script>import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US'import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'import '@univerjs/preset-sheets-core/lib/index.css'export default {  mounted() {    const { univer, univerAPI } = createUniver({      locale: LocaleType.EN_US,      locales: {        [LocaleType.EN_US]: mergeLocales(          UniverPresetSheetsCoreEnUS,        ),      },      presets: [        UniverSheetsCorePreset({          container: this.$refs.container,        }),      ],    })    univerAPI.createWorkbook({})    this.univerInstance = univer  },  beforeDestroy() {    this.univerInstance?.dispose()    this.univerInstance = null  },}</script><template>  <div ref="container" style="height: 600px" /></template>

How is this guide?

© 2026 DreamNum Co., Ltd.