700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > VUE+tinymce(富文本编辑器)

VUE+tinymce(富文本编辑器)

时间:2023-01-16 23:54:00

相关推荐

VUE+tinymce(富文本编辑器)

效果图:

VUE项目引入tinymce

1、tinymce安装以及下载

npm install @tinymce/tinymce-vue -savenpm install tinymce -save

①、安装完成以后,在安装目录node_modules中找到tinymce/skins目录,然后将 skins 目录拷贝到public(cli3是public目录,cli2应该是static目录)目录下。

②、tinymce默认是英文界面,需要下载一个中文包,选择对应的中文包进行下载。把这个中文包也放在public或static目录下面。

下载地址:Language Packages | Trusted Rich Text Editor | TinyMCE

我的项目使用版本:cli3+tinymce5,即放入public目录下并加了层名为tinymce的子目录,如下图:

2、封装成项目组件:vl-tinymce.vue

①、使用tinymce组件

<template><div class="tinymce-editor"><editor :id="tinymceId" v-model="myValue" :init="init" v-bind="$attrs" v-on="inputListeners"></editor></div></template>

②、引入包

import tinymce from 'tinymce/tinymce'import Editor from '@tinymce/tinymce-vue'import 'tinymce/themes/silver'

发现编辑器图片找不到,引入图标

import 'tinymce/icons/default/icons'

③、注册组件

tinymce/tinymce是一个组件,引入组件注册,直接使用

//注册组件components: {Editor}

④、初始化配置

mounted() {tinymce.init({})},

init: {language_url: '/tinymce/zh_CN.js', //指定中文包language: 'zh_CN',//中文skin_url: '/tinymce/skins/ui/oxide',//编辑器皮肤,height: 500,//高度browser_spellcheck: true, // 拼写检查branding: false, // 去水印elementpath: false, // 禁用编辑器底部的状态栏statusbar: false, // 隐藏编辑器底部的状态栏paste_data_images: true, // 允许粘贴图像menubar: false // 隐藏最上方menu}

⑤、引用插件

⑥、完善组件

问题一:页面实现数据回显时,tinymce无法回显绑定值

分析原因:数据赋值与tinymce组件渲染顺序导致

解决方案:

1)、当因当前页面刷新导致时

将需要回显值作为默认值添加上,考虑使用init》setup属性

init: {setup: (editor) => {// 初次化编辑器editor.on('init', () => {editor.setContent(this.value)})},},

2)、当因页面跳转导致时

考虑使用watch监听回显值

watch: {value(val) {this.$nextTick(() => tinymce.get(this.tinymceId).setContent(val))},},

3)、以上2点考虑都是基于所使用的组件最初使用时,所以我们采用一个标识记录一下当前组件是否最初使用,达到一次回显的目的即可。

我采用的标识名称为“isInit”,请参考我的代码分析。

问题二:通常我们设置内容后,光标会跑到最前面

解决方案:

加入一下代码

editor.selection.select(editor.getBody(),true);editor.selection.collapse(false);

⑦、我的代码

<template><div class="tinymce-editor"><editor :id="tinymceId" v-model.trim="myValue" :init="init" v-bind="$attrs" v-on="inputListeners"></editor></div></template><script>// 文档 http://tinymce.ax-/// 引入组件import tinymce from 'tinymce/tinymce' // tinymce默认hidden,不引入不显示import Editor from '@tinymce/tinymce-vue'// 引入富文本编辑器主题的js和cssimport 'tinymce/skins/content/default/content.css'import 'tinymce/themes/silver'import 'tinymce/icons/default/icons.min.js' // 解决了icons.js 报错Unexpected token '<'// 编辑器插件plugins// 更多插件参考:https://www.tiny.cloud/docs/plugins/import 'tinymce/plugins/image' // 插入上传图片插件import 'tinymce/plugins/media' // 插入视频插件import 'tinymce/plugins/table' // 插入表格插件import 'tinymce/plugins/lists' // 列表插件import 'tinymce/plugins/wordcount' // 字数统计插件import 'tinymce/plugins/link'import 'tinymce/plugins/code'import 'tinymce/plugins/preview'import 'tinymce/plugins/fullscreen'import 'tinymce/plugins/help'export default {inheritAttrs: false,components: {Editor,},name: 'Tinymce',props: {id: {type: String,default: function () {return new Date().getTime() + ''},},value: {type: String,default: '',},height: {type: Number,default: 300,},plugins: {type: [String, Array],default: 'link lists image code table wordcount media preview fullscreen help',},toolbar: {type: [String, Array],default:'bold italic underline strikethrough | fontsizeselect | formatselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent blockquote | undo redo | link unlink code lists table image media | removeformat | fullscreen preview',},},data() {const that = thisreturn {// 自动生成的idtinymceId: this.id,init: {selector: `#${this.tinymceId}`,language_url: '/tinymce/langs/zh_CN.js', // 语言包的路径language: 'zh_CN', //语言skin_url: '/tinymce/skins/ui/oxide', // skin路径height: this.height, //编辑器高度branding: false, //是否禁用“Powered by TinyMCE”menubar: false, //顶部菜单栏显示statusbar: false, //是否显示底部的状态栏plugins: this.plugins,toolbar: this.toolbar, // (自定义工具栏)// 此处为图片上传处理函数,这个直接用了base64的图片形式上传图片,// 如需ajax上传可参考https://www.tiny.cloud/docs/configure/file-image-upload/#images_upload_handlerimages_upload_handler: (blobInfo, success, failure) => {const img = 'data:image/jpeg;base64,' + blobInfo.base64()success(img)},setup: (editor) => {// 初次化编辑器editor.on('init', () => {that.isInit = true //告知是初始化\if (that.value) {editor.setContent(that.value)that.isInit = false}editor.on('input change undo redo', () => {// this.value = editor.getContent()//此处设置为false很好解决光标前置问题that.isInit = false})})},},myValue: this.value,isInit: false, //是否初始化}},computed: {inputListeners() {const newListeners = {...this.$listeners,input: (event) => {this.$emit('input', event)},}return newListeners},},mounted() {tinymce.init({})},beforeDestroy: function () {tinymce.remove(this.tinymceId)},methods: {/*** 获取富文本text类型内容*/getTextContent(){const editor = tinymce.get(this.tinymceId)return editor.getContent({'format' : 'text'})}},watch: {value(val) {//用户vue绑定回显if (this.isInit) {this.isInit = falsethis.$nextTick(() => {const editor = tinymce.get(this.tinymceId)editor.setContent(val) })}},},}</script>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。