123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- <template>
- <div>
- <article
- :id="id"
- v-loading="loading"
- element-loading-text="数据上传中,请稍后"
- element-loading-spinner="el-icon-loading"
- element-loading-background="rgba(0, 0, 0, 0.8)"
- >
- <div v-show="isEmpty && !edit" class="text-edit">
- {{ emptyText }}
- <el-button type="text" @click="ImmediateAddition">{{ inputButton }}</el-button>
- </div>
- <div v-show="edit">
- <el-tooltip effect="dark" content="单击‘编辑’,失去焦点 ‘保存’" placement="bottom">
- <editor v-model="inputValue" :class="'tinymce_'+id" :init="init" @input="changeText" />
- </el-tooltip>
- </div>
- <div v-show="!isEmpty && !edit">
- <pre class="text-pre" @click="ImmediateAddition" v-html="handlerText(value)" />
- </div>
- <div :id="'inputUpload_'+id" style="display: none" @click.stop="blur_textarea" />
- <div v-show="edit" class="control">
- <el-button size="small" @click="edit=false">取消</el-button>
- <el-button type="primary" size="small" @click.stop="blur_textarea">确定</el-button>
- </div>
- </article>
- </div>
- </template>
- <script>
- import { getContainImgHTMLNode } from '@/utils/handleTinymce'
- import tinymce from 'tinymce/tinymce'
- import Editor from '@tinymce/tinymce-vue'
- import 'tinymce/themes/silver/theme'
- import 'tinymce/icons/default/icons'
- export default {
- components: {
- Editor
- },
- props: {
- id: {
- type: String,
- default: '',
- required: true
- },
- value: {
- type: String,
- default: '',
- required: false
- },
- height: {
- type: Number,
- default: 200,
- required: false
- },
- emptyText: {
- type: String,
- default: '',
- required: false
- },
- inputButton: {
- type: String,
- default: '',
- required: false
- }
- },
- data() {
- return {
- loading: false,
- inputValue: '',
- edit: false,
- init: {
- auto_focus: true,
- language_url: '/tinymce/langs/zh_CN.js',
- language: 'zh_CN',
- skin_url: '/tinymce/skins/ui/oxide', // 编辑器需要一个skin才能正常工作,所以要设置一个skin_url指向之前复制出来的skin文件
- height: this.height,
- browser_spellcheck: true, // 拼写检查
- branding: false, // 去水印
- elementpath: false, // 禁用编辑器底部的状态栏
- statusbar: false, // 隐藏编辑器底部的状态栏
- paste_data_images: true, // 允许粘贴图像
- menubar: false, // 隐藏最上方menu
- fontsize_formats: '14px 16px 18px 20px 24px 26px 28px 30px 32px 36px', // 字体大小
- file_picker_types: 'image',
- images_upload_credentials: true,
- plugins: 'lists table textcolor wordcount contextmenu', // 引入插件
- toolbar: 'bold italic underline strikethrough | fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent table | undo redo | removeformat formatselect'
- }
- }
- },
- computed: {
- isEmpty() {
- return this.inputValue === null || this.inputValue.replace(/\s+/g, '') === ''
- }
- },
- watch: {
- value: {
- handler(newV, oldV) {
- this.inputValue = newV
- },
- immediate: true
- }
- },
- mounted() {
- document.body.addEventListener('click', e => {
- if (!document.getElementById(this.id)) {
- return false
- }
- const isContain = document.getElementById(this.id).contains(e.target)
- if (!isContain) {
- document.getElementById(`inputUpload_${this.id}`).click()
- }
- })
- tinymce.init({ selector: `.tinymce_${this.id}` })
- },
- methods: {
- ImmediateAddition() { // 立即添加(编辑)
- this.edit = true
- },
- changeText(e) { // 富文本内容改变
- this.inputValue = e
- },
- async blur_textarea() {
- if (this.edit) {
- this.loading = true
- try {
- this.inputValue = await getContainImgHTMLNode(this.inputValue)
- } catch (error) {
- this.loading = false
- throw error
- }
- this.loading = false
- this.edit = false
- this.$emit('update:value', this.inputValue)
- this.$emit('change', this.inputValue)
- }
- },
- handlerText(val) {
- if (val) {
- const reg = new RegExp(/<\/?p[^>]*>/gi)
- return val.replace(reg, '')
- }
- }
- }
- }
- </script>
- <style scoped lang="scss">
- article {
- padding: 0 30px 20px 30px;
- }
- .text-edit {
- color: #666666;
- font-size: 14px;
- display: flex;
- align-items: center;
- justify-content: flex-start;
- }
- .text-pre {
- white-space:pre-line;
- font-size: 14px;
- color: #333B4A;
- cursor: pointer;
- }
- /deep/ textarea {
- width: calc(100% - 40px);
- margin: auto;
- }
- .control {
- display: flex;
- justify-content: flex-end;
- margin-top: 10px;
- }
- </style>
|