Vue 백그라운드 관리 시스템 서식있는 텍스트 구성 요소 (1) tinymce

Vue 백그라운드 관리 시스템 서식있는 텍스트 구성 요소 (1) tinymce

소개

백그라운드 관리 시스템의 가장 중요한 기본 구성 요소 중 하나 인 서식있는 텍스트 구성 요소는 피트가 적은 서식있는 텍스트 제조업체에서 선택해야합니다. 여기에 사용 된 tinymce는 예쁘고 덜 움푹 들어갑니다.

주로 지침에 의존 (먼저 설치, 단계 생략)

 {
    
    
    "axios": "^0.18.0",
    "element-ui": "2.11.1",  
    "vue": "^2.6.10",    
    "vue-router": "^3.0.1"   
 }

tinymce : 5.0.8 소스 코드를 다운로드하는 방법은 여기에서 직접 사용되며 npm 다운로드는 패키징 속도에 큰 영향을 미치며 cdn을 사용할 수도 있습니다.

Tinymce 공식 웹 사이트 다운로드 주소

본문

1. tinymce 소스 코드를 다운로드하여 그림과 같이 vue-cli 3에서 생성 한 공용 폴더 아래의 static 폴더에 저장합니다.
여기에 사진 설명 삽입

언어 팩이 필요한 경우 zh_CN.js 파일을 별도로 다운로드하여 tinymce_5.0.8 폴더 아래의 lang 폴더에 넣습니다.

zh_CN.js 공식 웹 사이트 다운로드 주소

2. 항목 html 파일에서 가져 오기


<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="renderer" content="webkit" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
    />
    <meta name="description" content="<%= webpackConfig.name %>" />
    <meta name="robots" content="noindex,nofollow,noarchive" /> 
    <title>title</title>
  </head>
  <body>
    <script src="<%= BASE_URL %>static/tinymce_5.0.8/tinymce.min.js"></script>  
    <div id="app"></div> 
  </body>
</html>

3. 컴포넌트 Tinymce

파일 디렉토리

여기에 사진 설명 삽입

src / components / Tinymce / index.vue

<template>
  <div class="tinymce-container editor-container" :class="{fullscreen:fullscreen}">
    <textarea :id="tinymceId" class="tinymce-textarea" />
    <div class="editor-custom-btn-container">
      <multiple-upload class="editor-upload-btn" @success="imageSuccess" />
    </div>
  </div>
</template>

<script>
import axios from 'axios'

 // MultipleUpload组件见 https://blog.csdn.net/qq_39953537/article/details/100039094

import MultipleUpload from '@/components/MultipleUpload'
import plugins from './plugins' // 见下文
import toolbar from './toolbar' // 见下文

// 上传html片段接口根据自己项目更换
import {
     
      uploadHtml } from '@/api/upload'
export default {
     
     
  name: 'Tinymce',
  components: {
     
     
    MultipleUpload
  },
  props: {
     
     
    // 默认填充到富文本的html文件
    html: {
     
     
      type: String,
      default: ''
    },
    toolbar: {
     
     
      type: Array,
      default() {
     
     
        return []
      }
    },
    menubar: {
     
     
      type: Boolean,
      default: false
    },
    height: {
     
     
      type: Number,
      default: 400
    }
  },
  data() {
     
     
    return {
     
     
      hasChange: false,
      hasInit: false,
      tinymceId: 'vue-tinymce-' + +new Date(),
      fullscreen: false,
      value: '',
      editorContent: ''
    }
  },
  watch: {
     
     
    value(val) {
     
     
      this.$nextTick(() =>
        window.tinymce.get(this.tinymceId).setContent(val || '')
      )
    },
    html(val) {
     
     
      if (this.isUrl) {
     
     
        this.loadUrl(val)
      }
    }
  },
  created() {
     
     
    if (this.html && this.html.startsWith('http')) {
     
     
      this.loadUrl(this.html)
    } else {
     
     
      this.value = this.html + ''
      this.editorContent = this.html + ''
    }
  },
  mounted() {
     
     
    this.initTinymce()
  },
  activated() {
     
     
    this.initTinymce()
  },
  deactivated() {
     
     
    this.destroyTinymce()
  },
  destroyed() {
     
     
    this.destroyTinymce()
  },
  methods: {
     
     
    initTinymce() {
     
     
      window.tinymce.init({
     
     
        fontsize_formats: '12px 14px 16px 18px 20px 24px 36px',
        language: 'zh_CN',
        language_url: '/static/tinymce_5.0.8/langs/zh_CN.js',
        selector: `#${
       
       this.tinymceId}`,
        height: this.height,
        body_class: 'panel-body ',
        object_resizing: true,
        toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar,
        menubar: this.menubar,
        plugins: plugins,
        end_container_on_empty_block: true,
        powerpaste_word_import: 'clean',
        code_dialog_height: 450,
        code_dialog_width: 1000,
        advlist_bullet_styles: 'square',
        advlist_number_styles: 'default',
        default_link_target: '_blank',
        link_title: false,
        init_instance_callback: editor => {
     
     
          if (this.value) {
     
     
            editor.setContent(this.value)
          }
          this.hasInit = true
          editor.on('NodeChange Change KeyUp SetContent', () => {
     
     
            this.hasChange = true
            this.$emit('input', editor.getContent())
            this.editorContent = editor.getContent()
          })
        },
        setup(editor) {
     
     
          editor.on('FullscreenStateChanged', e => {
     
     
            this.fullscreen = e.state
          })
        }
      })
    },
    destroyTinymce() {
     
     
      if (window.tinymce.get(this.tinymceId)) {
     
     
        window.tinymce.get(this.tinymceId).destroy()
      }
    },
    loadUrl(url) {
     
     
      if (url && url.length > 0) {
     
     
        axios
          .get(url)
          .then(response => {
     
     
            // 处理HTML显示
            this.value = response.data
            this.editorContent = response.data
            this.$emit('subLoadUrlToHtml', response.data)
            this.$emit('input', response.data)
          })
          .catch(() => {
     
     
            this.value = '服务器数据加载失败,请重试!'
          })
      }
    },
    // 设置编辑器内容
    setContent(value) {
     
     
      window.tinymce.get(this.tinymceId).setContent(value)
    },
    // 获取编辑器内容
    getContent() {
     
     
      window.tinymce.get(this.tinymceId).getContent()
    },
    // 图片上传成功后填充到富文本编辑器
    async imageSuccess(urlList) {
     
     
      try {
     
     
        let imageTemplateList = ''
        urlList.forEach(item => {
     
     
          const image = `<img style="max-width:100%;" src="${
       
       item}">`
          imageTemplateList = imageTemplateList + image
        })
        window.tinymce.get(this.tinymceId).insertContent(imageTemplateList)
        this.$message({
     
     
          message: '上传成功!',
          type: 'success'
        })
      } catch (error) {
     
     
        console.log(error)
        this.$message({
     
     
          message: error,
          type: 'error'
        })
      }
    },
    // 编辑器内容上传到cos,调用返回url
    async content2Url() {
     
     
      try {
     
     
        const res = await uploadHtml(this.editorContent)
        return res
      } catch (error) {
     
     
        this.$message({
     
     
          message: error.data.message,
          type: 'error'
        })
      }
    }
  }
}
</script>

<style lang='scss' >
#tinymce {
     
     
  background-color: blue;
  p {
     
     
    margin: 0;
  }
}
.tinymce-container {
     
     
  position: relative;
}
.tinymce-container >>> .mce-fullscreen {
     
     
  z-index: 10000;
}
.tinymce-textarea {
     
     
  visibility: hidden;
  z-index: -1;
}
.editor-custom-btn-container {
     
     
  position: absolute;
  right: 4px;
  top: 4px;
  /*z-index: 2005;*/
}
.fullscreen .editor-custom-btn-container {
     
     
  z-index: 10000;
  position: fixed;
}
.editor-upload-btn {
     
     
  display: inline-block;
}
// 隐藏底部logo栏
.mce-edit-area + .mce-statusbar {
     
     
  opacity: 0;
  height: 0;
}
</style>



src / components / Tinymce / plugins.js

const plugins = [
  'advlist anchor autolink autosave code codesample directionality emoticons fullscreen hr image imagetools importcss insertdatetime link lists media nonbreaking noneditable pagebreak  preview print save searchreplace spellchecker tabfocus table template  textpattern visualblocks visualchars wordcount paste'
]

export default plugins

src / components / Tinymce / toolbar.js

const toolbar = ['formatselect fontsizeselect forecolor backcolor bold italic underline strikethrough alignleft aligncenter alignright outdent indent    removeformat  hr undo redo']

export default toolbar

4. 사용

<template>
    <div>
        <tinymce
        ref="tinymce"
        :height="500"
        :html="html"
        @input="getContent"
        />
    </div>
</template>

<script>
import AppCropper from '@/components/Cropper'
export default {
     
     
  name: 'GoodsForm',
  components: {
     
     
    AppCropper
  },
  data() {
     
     
    return {
     
     
      html: 'https://ebusiness-1255313385.cosbj.myqcloud.com/image/20190823/center2019082304054532.html',
      content:''
    }
  },
  methods: {
     
     
      // 获取编辑器内容
    getContent(content) {
     
     
      this.content = content
    },
    // 编辑器内容转换成在线url
    async getcontent2Url() {
     
     
      try {
     
     
        const htmlUrl =  await this.$refs.tinymce.content2Url()
        return htmlUrl
      } catch (error) {
     
     
        console.log(error)
      }
    }

  }
}
</script>
 

5. 효과 사용
여기에 사진 설명 삽입

참조 링크

1. https://github.com/PanJiaChen/vue-element-admin/blob/master/src/components/Tinymce/index.vue

2. Tinymce 중국어 문서

추천

출처blog.csdn.net/qq_39953537/article/details/100041453