组件
<template>
<div class="editor">
<TinymceEditor v-model="myValue" :init="completeSetting" :disabled="disabled" />
</div>
</template>
<script setup>
//引入自己接口
import { goodsAlbumFilesUploadImage } from '@/api/commodity/commodity'
import tinymce from 'tinymce/tinymce'
import TinymceEditor from '@tinymce/tinymce-vue'
import 'tinymce/themes/silver/theme'
import 'tinymce/icons/default/icons'
import 'tinymce/plugins/autolink'
import 'tinymce/plugins/autoresize'
import 'tinymce/plugins/colorpicker'
import 'tinymce/plugins/contextmenu'
import 'tinymce/plugins/fullscreen'
import 'tinymce/plugins/hr'
import 'tinymce/plugins/image'
import 'tinymce/plugins/imagetools'
import 'tinymce/plugins/insertdatetime'
import 'tinymce/plugins/link'
import 'tinymce/plugins/lists'
import 'tinymce/plugins/media'
import 'tinymce/plugins/preview'
import 'tinymce/plugins/table'
import 'tinymce/plugins/textcolor'
import 'tinymce/plugins/wordcount'
import 'tinymce/plugins/code'
import 'tinymce/plugins/searchreplace'
const props = defineProps({
modelValue: {
type: String,
default: ''
},
setting: {
type: Object,
default: () => {}
},
disabled: {
type: Boolean,
default: false
}
})
const emit = defineEmits(['update:modelValue'])
const defaultSetting = ref({
language_url: 'tinymce/langs/zh_CN.js',
language: 'zh_CN',
skin_url: 'tinymce/skins/ui/oxide',
min_height: 250,
max_height: 600,
selector: 'textarea',
plugins: 'autolink autoresize contextmenu fullscreen hr image imagetools insertdatetime link lists media preview table textcolor wordcount code searchreplace',
toolbar: [
'|undo redo | formatselect | bold italic strikethrough forecolor | alignleft aligncenter alignright alignjustify |',
'|fontsizeselect| bullist numlist outdent indent | hr image table searchreplace removeformat| '
],
branding: false,
menubar: false,
toolbar_mode: 'sliding',
insertdatetime_formats: [
'%Y年%m月%d日',
'%H点%M分%S秒',
'%Y-%m-%d',
'%H:%M:%S'
],
image_dimensions: false,
content_style: 'img{width:100%;height:auto;}',
// 使用base64上传图片
// images_upload_handler: (blobInfo, success) => {
// const img = 'data:image/jpeg;base64,' + blobInfo.base64()
// success(img)
// }
// 自定义图片上传
images_upload_handler: (blobInfo, success, failure) => {
const formData = new FormData()
formData.append('file', blobInfo.blob())
//使用自己接口或者axios
goodsAlbumFilesUploadImage(formData).then(res => {
console.log(res.code)
if (res.code == 200) {
let file = res.data.url
success(file)
return
}
failure('上传失败')
}).catch(error => {
console.log(error)
failure('上传出错')
})
}
})
const myValue = ref(props.modelValue)
const completeSetting = computed(() => {
return Object.assign(defaultSetting.value, props.setting)
})
watch(() => myValue.value, newValue => {
emit('update:modelValue', newValue)
})
watch(() => props.modelValue, newValue => {
myValue.value = newValue
})
onMounted(() => {
tinymce.init({})
})
</script>
<style lang="scss" scoped>
:deep(.tox-tinymce) {
border: 1px solid #dcdfe6;
border-radius: 4px;
}
</style>
处理上传图片样式(宽度100%)小程序适配
// 处理富文本展示
function formatRichText(html) {
// eslint-disable-next-line no-unused-vars
let newContent = html.replace(/<img[^>]*>/gi, function(match, capture) {
match = match.replace(/style="[^"]+"/gi, '').replace(/style='[^']+'/gi, '')
match = match.replace(/width="[^"]+"/gi, '').replace(/width='[^']+'/gi, '')
match = match.replace(/height="[^"]+"/gi, '').replace(/height='[^']+'/gi, '')
return match
})
// eslint-disable-next-line no-unused-vars
newContent = newContent.replace(/style="[^"]+"/gi, function(match, capture) {
match = match.replace(/width:[^;]+;/gi, 'max-width:100%;').replace(/width:[^;]+;/gi, 'max-width:100%;')
return match
})
newContent = newContent.replace(/<br[^>]*\/>/gi, '')
// eslint-disable-next-line no-useless-escape
newContent = newContent.replace(/\<img/gi, '<img style="max-width:100%;height:auto;display:block;margin-top:0;margin-bottom:0;"')
return newContent
}
export default formatRichText
页面使用
<editor v-model="form.content" style="height: 100%; overflow: hidden;" />