• 欢迎访问春风博客

Nuxt 刷新使用富文本 报错 Document / Window not defined 究极解决方案

运维笔记 yongchao, li 4年前 (2020-06-24) 1682次浏览 0个评论

安装方法:npm install -d vue-quill-editor quill vue-cropper

官网:

vue-quill-editor:https://quilljs.com/

git:https://github.com/surmon-china/vue-quill-editor

vue-cropper:https://github.com/xyxiao001/vue-cropper

nuxt框架基于vue的服务端渲染,有报错 Document / Window not defined 的问题,使用富文本编辑器进行组件单独引入的时候会报错,在组件中使用

if (process.client) {
  require('external_library')
}

之后element会显示不出来,所以在使用这种引入插件的时候建议直接在

plugins文件夹内直接全局注册,使用服务器渲染
plugins: [
    '@/plugins/element-ui',
    '@/plugins/bootstrap-vue',
    { src: '@/plugins/map', ssr: false },
    { src: '@/plugins/vue-quill-editor', ssr: false },
    { src: '@/plugins/vue-cropper', ssr: false }
  ],

组件使用代码:(网上摘取)

在使用上传的时候action是传输一个链接地址,如果想根据自己定义的axios上传需要添加一个auto-upload=”false”意思不取消自动上传更据:on-change=”onChange”(文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用)动作进行上传

<template>
  <div>
    <!-- 图片上传组件-->
    <el-upload
      :before-upload="beforeUpload"
      :show-file-list="false"
      accept="image/*"
      action=""
      class="avatar-uploader"
      hidden
      name="file"
      type='file'>
      <el-button size="small" type="primary">点击上传图片 到 文本编辑器</el-button>
    </el-upload>
    <!-- 编辑器组件-->
    <quill-editor
      :options="editorOption"
      @change="onEditorChange($event)"
      class="editor"
      ref="myQuillEditor"
      v-model="content">
    </quill-editor>
    <!-- 图片裁剪组件-->
    <el-dialog :visible.sync="isShowCropper" top="5vh">
      <VueCropper
        :autoCrop="option.autoCrop"
        :autoCropHeight="option.autoCropHeight"
        :autoCropWidth="option.autoCropWidth"
        :canScale="option.canScale"
        :fixed="option.fixed"
        :fixedNumber="option.fixedNumber"
        :img="option.img"
        :info="option.info"
        :outputSize="option.outputSize"
        :outputType="option.outputType"
        ref="cropper"
        style="height:600px;margin:20px 0"
      >
      </VueCropper>
      <br/>

      <el-button @click="onCubeImg()" type="primary">生成图片</el-button>
      <el-button @click="isShowCropper = false">取消</el-button>
    </el-dialog>
  </div>
</template>
<script>
  // 富文本工具栏配置
  const toolbarOptions = [
    ['bold', 'italic', 'underline', 'strike'], // 加粗 斜体 下划线 删除线
    ['blockquote', 'code-block'], // 引用  代码块
    [{ header: 1 }, { header: 2 }], // 1、2 级标题
    [{ list: 'ordered' }, { list: 'bullet' }], // 有序、无序列表
    [{ script: 'sub' }, { script: 'super' }], // 上标/下标
    [{ indent: '-1' }, { indent: '+1' }], // 缩进
    // [{'direction': 'rtl'}],                         // 文本方向
    [{ size: ['small', false, 'large', 'huge'] }], // 字体大小
    [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题
    [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
    [{ font: [] }], // 字体种类
    [{ align: [] }], // 对齐方式
    ['clean'], // 清除文本格式
    ['link', 'image', 'video'] // 链接、图片、视频
  ]


  import 'quill/dist/quill.core.css'
  import 'quill/dist/quill.snow.css'
  import 'quill/dist/quill.bubble.css'
  import { uImage } from '@/api/uploadImage.js'

  export default {
    name: 'textEditor',
    components: {},
    props: {
      /*编辑器的内容*/
      value: {
        type: String
      },
      /*图片大小*/
      maxSize: {
        type: Number,
        default: 4000 //kb
      }
    },
    data() {
      return {
        // 富文本数据
        content: '',
        quillUpdateImg: false, // 根据图片上传状态来确定是否显示loading动画,刚开始是false,不显示
        editorOption: {
          theme: 'snow', // or 'bubble'
          placeholder: '请输入您想输入的内容',
          modules: {
            toolbar: {
              container: toolbarOptions,
              // 和上传按钮进行绑定
              handlers: {
                image: function(value) {
                  console.log(value)
                  if (value) {
                    // 触发input框选择图片文件
                    document.querySelector('.avatar-uploader input').click()
                  } else {
                    this.quill.format('image', false)
                  }
                }
              }
            }
          }
        },
        // 切图器数据
        option: {
          img: '',                         // 裁剪图片的地址
          info: true,                      // 裁剪框的大小信息
          outputSize: 1,                   // 裁剪生成图片的质量
          outputType: 'png',               // 裁剪生成图片的格式
          canScale: true,                 // 图片是否允许滚轮缩放
          autoCrop: true,                  // 是否默认生成截图框
          autoCropWidth: 150,              // 默认生成截图框宽度
          autoCropHeight: 150,             // 默认生成截图框高度
          fixed: true,                    // 是否开启截图框宽高固定比例
          fixedNumber: [4, 4]             // 截图框的宽高比例
        },
        isShowCropper: false,
        isClient: true,
        width: '150px',
        height: '150px'
      }
    },
    methods: {
      // 上传切图前调用
      beforeUpload(file) {
        /**
         * URL.createObjectURL(file)生成本地的url
         * 返回false终止了自动上传
         * */
        this.option.img = URL.createObjectURL(file)
        this.option.autoCropWidth = this.width
        this.option.autoCropHeight = this.height
        this.isShowCropper = true
        return false
      },
      // 确定裁剪图片
      onCubeImg() {
        // 获取cropper的截图的base64 数据data
        this.$refs.cropper.getCropData(data => {
          //截取bas64 截取base64的格式 和 图片的后缀名
          let baseSplit= data.split(',')
          let format = baseSplit[0].split('/')[1].split(';')[0]
          //获取base64格式的信息
          let base = ''
          if (process.client) {
            base = window.atob(baseSplit[1])
          }
          //转格式:base64转图片
          /**
           *格式为:File
           * lastModified: 1593134876792
           * lastModifiedDate: Fri Jun 26 2020 09:27:56 GMT+0800 (中国标准时间) {}
           * name: "img.png"
           * size: 15407
           * type: "image/png"
           * webkitRelativePath: ""
           * */
          let index = base.length
          let u8arr = new Uint8Array(index)
          while (index--) {
            u8arr[index] = base.charCodeAt(index)
          }
          let blods = new File([u8arr],'img.' + format,{type: 'image/' + format })

          /**
           * 建立一个formData表单,之后把上面的base64转换后的格式使用append传递给FormData
           * */
          let fromData = new FormData()
          fromData.append('file',blods)

          this.$notify({
            title: '成功',
            message: '正在上传中',
            type: 'success'
          });
          //发出网络请求
          uImage(fromData).then(res => {
            this.$notify({
              title: '成功',
              message: '图片上传成功',
              type: 'success'
            });
            // 获取富文本组件实例
            let quill = this.$refs.myQuillEditor.quill
            if(res.code === 200){
              // 获取光标所在位置
              /**
               *  quill.insertEmbed(length, 'image', res.data.url)
               *  图片显示的位置,根据length后的位置显示
               * */
              if (quill.getSelection() && quill.getSelection().index) {
                let length = quill.getSelection().index
                quill.insertEmbed(length, 'image', res.data.url)
              } else {
                let length = 0
                quill.insertEmbed(length, 'image', res.data.url)
              }
              // 调整光标到最后
              quill.setSelection(length + 1)
            }else {
              console.log(res.data.code)
              this.$notify({
                title: '警告',
                message: '图片上传失败',
                type: 'warning'
              });
            }
            this.isShowCropper = false
            // 先将显示图片地址清空,防止重复显示
            this.option.img = ''
          })
        })
      },
      onEditorChange() {

        console.log(this.content)
        //富文本内容改变事件 发送给父级元素
        this.$emit('change', this.content)
      }
    },
    mounted() {
      setTimeout(() => {
        this.content = this.value
      }, 500)
    }
  }
</script>
<style lang="scss">

</style>

 


ChunBlog.Com , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Nuxt 刷新使用富文本 报错 Document / Window not defined 究极解决方案
喜欢 (17)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址