Nuxt3 window is not defined error

Problem
Using window/document directly in nuxt will report ReferenceError: window is not defined

Reason
The reason is actually relatively simple. Since nextjs is server-side rendering, it will generate HTML after pre-rendering the page, and then send it to the client. Therefore, it cannot recognize the object method of window/document browser when rendering.

solution, a

This method is relatively simple and rude. It directly determines whether the window exists and then executes the corresponding code (document is the same)

if (typeof window !== 'undefined') {
    
    
    console.log('window:', window);
 }

Solution, 2.
Modify the nuxt.config.js file
and add the following configuration to nuxt.config.jsthe file:

import createPersistedState from 'vuex-persistedstate'
import path from 'path'

export default {
  // 其它配置...
  build: {
    transpile: ['@logicflow/core'],
    extend(config, { isDev, isClient }) {
      if (process.env.NODE_ENV === 'production' && process.client) {
        config.optimization.splitChunks.maxSize = 200000;
      }
    }
  },
  plugins: [
    // 在这里引入插件
    '~/plugins/logicflow.js',
    { src: '~/plugins/localStorage.js', ssr: false } // 忽略服务端渲染
  ]
}

In the above code, we used two plugins: ~/plugins/logicflow.jsand ~/plugins/localStorage.js.

~/plugins/logicflow.jsIt is used to introduce @logicflow/coredependent libraries on demand and mount them on the prototype of the Vue instance for use in Vue components.

Create a file in the root directory of the project ~/plugins/logicflow.jsand add the following code:

import LogicFlow from '@logicflow/core'

export default (context, inject) => {
  // 只在客户端运行
  if (process.client) {
    inject('LogicFlow', LogicFlow)
  }
}

In the above code, we use the plug-in mechanism provided by Nuxt.js to LogicFlowinject the object into Vuethe prototype of the instance, and injectmount it into the Vue component through the function for use in the component.

~/plugins/localStorage.jsUsed to solve local storage problems. This plugin requires @nuxtjs/universal-storagea dependency library, please make sure it has been installed in the first step.

Create a file in the root directory of the project ~/plugins/localStorage.jsand add the following code:

import createPersistedState from 'vuex-persistedstate'

export default ({ store }) => {
  createPersistedState({
    key: 'my-app',
    paths: ['user', 'token'] // 自定义需要本地存储的属性
  })(store)
}

In the above code, we use a dependent library, which can automatically save the data in the local cache vuex-persistedstatewhen the page is refreshed, so that it can be restored when it is used next time.Vuex

solution, three

3. Use in Vue components

When using LogicFlow in Vue components, you need to first

For example:

<template>
  <div id="box"></div>
</template>

<script>
import { NuxtApp } from '@nuxt/types/app'
import LogicFlow from '@logicflow/core'

export default {
  async mounted() {
    // 获取Nuxt.js实例
    const nuxt: NuxtApp = this.$nuxt

    // 等待客户端初始化完成
    await nuxt.ready()

    // 创建LogicFlow实例
    const lf = new LogicFlow({
      container: document.querySelector('#box'),
      width: 800,
      height: 600
    })
  }
}
</script>

In the above code, we created an LogicFlowinstance in the mounted lifecycle function of the Vue component and mounted it to <div id="box">the element. When creating a LogicFlow instance, we used document.querySelector('#box')to get the DOM node, and this.$nuxtgot the Nuxt.js instance by.

When using dependent libraries in Vue components @logicflow/core, you need to ensure that the client has been initialized, otherwise errors may occur. Therefore, in the Vue component, we used to await nuxt.ready()wait for the client initialization to complete before creating the LogicFlow instance.

Guess you like

Origin blog.csdn.net/weixin_55042716/article/details/129983652