Vue+iView+tinyMce开发前端项目过程中遇到的坑!!!

1,337 阅读5分钟

此篇文章是记录在开发后台管理项目时,遇到的一些问题,及解决方案。 项目使用Vue开发,目前使用UI为iView,富文本采用tinyMCE

因为我以往是纯Java后端开发,因公司需要,在写后端代码的同时,也需要同时写前端代码,所以本人的前端知识很零散,甚至小白,如有一些基础问题,请不要惊讶与谩骂,谢谢!

因为此篇文章是在开发项目中段才开始写的,此篇文章并未收录所有在项目开发中开发的问题。

如果我的经历能帮助到你,我将非常的开心,让我们一起进步!

另外,到项目完结前,只要在项目更新的过程中遇到问题,都将继续更新...

项目已经不再继续做下去了,后续如果还有做相关方面的需求,再更新吧

1. Vue本身遇到的问题

1.1 异常

1.1.1 报错Computed property "****" was assigned to but it has no setter.

  • 原因:值通过computed定义,但是需要在过程中对此属性进行设置新值,报出此异常。
  • 解决:通过data定义变量,通过watch原变量进行逻辑赋值,如果是复杂对象,可以采用'deep'watch赋值
  •   props:{
      	parentDemo:{
          	type:String,
              defalut:""
          }
      },
      data() {
      	return {
          	demo:this.parentDemo;
          }
     },
     watch: {
      	parentDemo:{
          	handler(value) {
              	this.demo = value;
              },
              deep:true
          }
      }
    
  • 取缔原解决方案原因:使用原方法,如果是两个组件之间交互,会导致子组件可以改变父组件的值,而父组件无法子组的值(如以下情况):
  model: {
    prop: "data",
    event: "changeDetail"
  },
  props: {
    data: {
      type: String,
      default: () => ""
    },
  },
  watch: {
  	childData(newValue){
    	this.$emit("changeDetail",newValue)
    }
  },
  data () {
    return {
    	childData:this.data
    }
  }
  • 新的解决方法,采用computed定义变量,并定义对应的get,set方法:
  model: {
    prop: "data",
    event: "changeDetail"
  },
  props: {
    data: {
      type: String,
      default: () => ""
    }
  },
  computed: {
    childData: {
      get () {
        return this.data; // 此处相当于原来的childData(){return this.data}
      },
      set (value) {
        this.$emit("changeDetail", value) // 通过set来完成对父组件的控制
      }
    }
  },

1.1.2 报错: Error in callback for watcher "addForm": "TypeError: Cannot read property 'call' of undefined"

  • 原因:watch函数错写或不完整
  • 解决:检查watch函数是否完整、准确,有遇到handler写漏最后一个'r'

2. iView遇到的问题

3. tinyMce遇到的问题

3.1 tinyMce的安装

3.1.1 参考的文章

3.1.2 安装到使用的过程

3.1.2.1 安装
  1. yarn add @tinymce/tinymce-vue -S 或 npm i @tinymce/tinymce-vue -S
  2. yarn add tinymce -S 或 npm i tinymce -S
  3. 复制node_modules/tinymce整个目录复制至public/目录下
  4. (如无须语言包,此步忽略)到官网地址:www.tiny.cloud/get-tiny/la…
3.1.2.2 使用
  1. 在需要使用富文本的组件中引入:
import tinymceEditor from "@tinymce/tinymce-vue"
  1. 在components中引用:
components:{
	"tinymce-editor":tinymceEditor;
}
  1. 在data中定义一个tinymce的配置变量:
init: {
        base_url: '/tinymce', // 指定本地tinymce目录
        language: "zh_CN", 
        language_url: '/tinymce/langs/zh_CN.js',
        height: 430, // 文本框的高度
        plugins:"link lists image code table wordcount", // 对应文本框的功能栏
        toolbar:"bold italic underline strikethrough | fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify|bullist numlist |outdent indent blockquote | undo redo | link unlink image code | removeformat", // 对应文本框的工具栏
        branding: false,
        images_upload_handler:(blobInfo, success,failure)=> {
          try {
            success(this.uploadImage(blobInfo.blob()));
            this.$Message.success("上传图片成功");
          } catch (e) {
            this.$Message.error(e);
            failure("上传图片失败");
          }
        } // 对应的文本框中上传图片的处理方式
     },
  1. 放置组件到所在位置:
<div>
    <tinymce-editor :init="init" v-model="form.content"></tinymce-editor>
</div>
  1. 上传方法自定义:
uploadImage (file) {
      return new Promise((resolve, reject) => {
      	// 为对额外参数的效验
        let valid = this.validatorUploadData();
        if (valid === true) {
        // 自己封装的axios上传接口,其中url为后端上传地址,file为上传的图片,otherParams为额外需要携带的参数
          apiUtils.singleUpload(this.uploadUrl, file, this.otherParams).then(res => {
            if (res.ret) {
              resolve(res.data);
            } else {
              reject(new Error(res.errMsg))
            }
          })
        } else {
          reject(new Error(valid))
        }
      })
    }

3.2 遇到的问题

3.2.1 按第3篇文章安装后,运行时,还是提示:“npm i @tinymce/tinymce-vue -S”;

  • 原因:没有理解这句话:“需要把node_modules下的tinymce包下的资源拷贝到项目本地,以便本地访问这些资源。”
  • 解决:通过第2篇文章的提示的搬运提示:复制node_modules/tinymce目录下所有文件至public/目录下。后面了解到,一般的富文本框都需要作相关的操作。

3.2.2 屏蔽@tinymce/tinymce-vue的key提示

  • 原因:@tinymce/tinymce-vue需要使用key,不然都会出现提示;
  • 解决:通过全局css增加以下样式(建议增加使用/deep/穿透)
// 隐藏 tinymce alert
.tox .tox-notifications-container .tox-notification {
  display: none;
}

3.2.3 全屏预览

3.2.4 图片自适应问题

  • tinymce的上传组件,在上传后或使用已有图片链接时,会自动加载图片的width和height,如果编辑区域的width小于图片区域,将会出现横向拉条,不仅不直观,还非常的影响使用。此时如果需要手动输入width和height非常的麻烦(多图片编辑时),为此产生了想要使用一个默认的值作为样式
  • 通过简单的修改对应js,使用固定的值,此处采用width:100%和height:auto作为默认值,通过改造后,无论是编辑框还是预览,都不会因为图片尺寸而产生横向拉条。当然,如果想要知道原图的尺寸信息,需要在更加深入的改造,因目前暂无此需求,不作深入(要研究的,可参考var makeItems = function (info)这个对象的相关定义)。
var imageSize = function (editor) {
      return function (url) {
        return getImageSize(editor.documentBaseURI.toAbsolute(url)).then(function (dimensions) {
          return {
            width: String(dimensions.width), // 此处修改为width: '100%',
            height: String(dimensions.height) // 此处修改为height:'auto'
          };
        });
      };
    };
    
    var defaultData = function () {
      return {
        src: '',
        alt: '',
        title: '',
        width: '',	// 此处默认为'100%'
        height: '',	// 此处默认为'auto'
        class: '',
        style: '',
        caption: false,
        hspace: '',
        vspace: '',
        border: '',
        borderStyle: '',
        isDecorative: false
      };
    };

3.2.4 readonly参数配置

  • 根据文档,在上面的安装步骤的init参数配置中,直接增加readonly参数,并赋值为true是无效的
  • 解决:还需要通过setup函数,把通过setMode('readonly)才会最终生效
init: {
	selector: '#fetures',
	readonly: true,
	inline: true,
	setup: function (editor) {
		editor.setMode("readonly")
	}
}