没有定义窗口
如果您在nuxt.config.js 中设置ssr: true 并将您的自定义VCKEditor.vue 放入组件文件夹中,Nuxt 将通过服务器端扫描组件文件夹并且它不知道window 关键字是@ckeditor/ckeditor5-vue2 中的 JavaScript 对象。
你可以看到更多关于components doc的信息。
我不喜欢使用process.client 来检查 ssr 模式。
我有两种解决方案,请选择一种
- 在
nuxt.config.js 中设置components: false。
- 将您的自定义
VCKEditor.vue 移动到外部的组件文件夹中。
最后,将自定义VCKEditor.vue注册为插件,并在nuxt.config.js中设置插件ssr: false。
这里是sample project。
代码sn-p
const path = require('path')
const CKEditorWebpackPlugin = require("@ckeditor/ckeditor5-dev-webpack-plugin")
const CKEditorStyles = require("@ckeditor/ckeditor5-dev-utils").styles
export default {
// ignore other settings...
ssr: true,
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
{
src: '~/plugins/ckeditor.js', ssr: false
},
],
// set false to disable scan the components folder
components: false,
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {
transpile: [/ckeditor5-[^/\\]+[/\\]src[/\\].+\.js$/],
plugins: [
// If you set ssr: true that will cause the following error. This error does not affect the operation.
// ERROR [CKEditorWebpackPlugin] Error: No translation has been found for the zh language.
new CKEditorWebpackPlugin({
// See https://ckeditor.com/docs/ckeditor5/latest/features/ui-language.html
language: "zh",
additionalLanguages: 'all',
addMainLanguageTranslationsToAllAssets: true,
})
],
// If you don't add postcss, the CKEditor css will not work.
postcss: CKEditorStyles.getPostCssConfig({
themeImporter: {
themePath: require.resolve("@ckeditor/ckeditor5-theme-lark")
},
minify: true
}),
extend(config, ctx) {
// If you do not exclude and use raw-loader to load svg, the following errors will be caused.
// Cannot read property 'getAttribute' of null
const svgRule = config.module.rules.find(item => {
return /svg/.test(item.test);
})
svgRule.exclude = [path.join(__dirname, 'node_modules', '@ckeditor')];
// add svg to load raw-loader
config.module.rules.push({
test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
use: ["raw-loader"]
})
}
}
}
- components/editor/VCKEditor.vue
<template>
<ckeditor
v-model="editorData"
:editor="editor"
:config="editorConfig"
></ckeditor>
</template>
<script>
import CKEditor from '@ckeditor/ckeditor5-vue2'
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor'
import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold'
import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic.js'
import Underline from '@ckeditor/ckeditor5-basic-styles/src/underline'
import Strikethrough from '@ckeditor/ckeditor5-basic-styles/src/strikethrough'
// less Heading + Essentials plugin can't input the text
import Heading from '@ckeditor/ckeditor5-heading/src/heading'
import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials'
import ImageUpload from '@ckeditor/ckeditor5-image/src/imageupload'
import ImageInsert from '@ckeditor/ckeditor5-image/src/imageinsert'
import AutoImage from '@ckeditor/ckeditor5-image/src/autoimage'
import Image from '@ckeditor/ckeditor5-image/src/image'
import ImageResizeEditing from '@ckeditor/ckeditor5-image/src/imageresize/imageresizeediting'
import ImageResizeHandles from '@ckeditor/ckeditor5-image/src/imageresize/imageresizehandles'
import Base64UploadAdapter from '@ckeditor/ckeditor5-upload/src/adapters/base64uploadadapter'
export default {
name: 'VCKEditor',
components: { ckeditor: CKEditor.component },
props: {
value: {
type: String,
},
},
computed: {
editorData: {
get() {
return this.value
},
set(value) {
this.$emit('input', value)
},
},
},
data() {
return {
editor: ClassicEditor,
editorConfig: {
plugins: [
Bold,
Italic,
Underline,
Strikethrough,
Heading,
Essentials,
ImageUpload,
ImageInsert,
AutoImage,
Image,
ImageResizeEditing,
ImageResizeHandles,
Base64UploadAdapter,
],
toolbar: {
items: [
'heading',
'|',
'bold',
'italic',
'underline',
'strikethrough',
'|',
'insertImage',
],
},
language: 'zh',
},
}
},
}
</script>
import Vue from 'vue';
import VCKEditor from "../components/editor/VCKEditor.vue";
Vue.component('v-ckeditor', VCKEditor);
<template>
<client-only>
<v-ckeditor v-model="text" />
</client-only>
</template>
<script>
export default {
data() {
return {
text: 'Hello World!!',
}
},
}
</script>