美文网首页
vue-cli3集成tinymce5富文本

vue-cli3集成tinymce5富文本

作者: 领带衬有黄金 | 来源:发表于2020-04-23 17:14 被阅读0次

1. 安装所需包

npm install @tinymce/tinymce-vue -S
npm install tinymce -S

若无法进行安装,将下面的配置到package.json中执行npm install

"@tinymce/tinymce-vue": "^2.0.0",
"tinymce": "^5.0.3"

2. 下载中文语言包

tinymce提供了很多的语言包,在这里我们下载(可能需要VPN才能访问)中文语言包

2.1 使用

在public目录下新建tinymce,将上面下载的语言包解压到该目录
在node_modules里面找到tinymce,将skins目录复制到public/tinymce里面
最终形成以下目录形式:

image.png
无法将插件翻译--5.0暂时还没有中文包

3. 封装组件

tinymce-editor.vue

<template>
  <div class="tinymce-editor">
    <editor v-model="myValue"
            :init="init"
            :disabled="disabled"
            @onClick="onClick">
    </editor>
  </div>
</template>
<script>
import tinymce from 'tinymce/tinymce'
import Editor from '@tinymce/tinymce-vue'
import 'tinymce/themes/silver'
// 编辑器插件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/skins/ui/oxide/skin.css'

export default {
  components: {
    Editor
  },
  props: {
    //传入一个value,使组件支持v-model绑定
    baseUrl: {
      type: String,
      default: ''
    },
    value: {
      type: String,
      default: ''
    },
    disabled: {
      type: Boolean,
      default: false
    },
    plugins: {
      type: [String, Array],
      default: 'lists image media table wordcount'
    },
    toolbar: {
      type: [String, Array],
      default: 'undo redo |  formatselect | bold italic forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | lists image media table '
    }
  },
  data () {
    return {
      //初始化配置
      init: {
        language_url: `/static/tinymce/langs/zh_CN.js`,
        language: 'zh_CN',
        skin_url: `/static/tinymce/skins/ui/oxide`,
        content_css: `/static/tinymce/skins/content/default/content.css`,
        height: 300,
        plugins: this.plugins,
        toolbar: this.toolbar,
        branding: false,
        menubar: false,
        //此处为图片上传处理函数,这个直接用了base64的图片形式上传图片,
        //如需ajax上传可参考https://www.tiny.cloud/docs/configure/file-image-upload/#images_upload_handler
        images_upload_handler: (blobInfo, success, failure) => {
          const img = 'data:image/jpeg;base64,' + blobInfo.base64()
          success(img)
        },
      },
      myValue: this.value,
    }
  },
  mounted () {
    tinymce.init({})
  },
  methods: {
    //添加相关的事件,可用的事件参照文档=> https://github.com/tinymce/tinymce-vue => All available events
    //需要什么事件可以自己增加
    onClick (e) {
      this.$emit('onClick', e, tinymce)
    },
    //可以添加一些自己的自定义事件,如清空内容
    clear () {
      this.myValue = ''
    }
  },
  watch: {
    value (newValue) {
      this.myValue = newValue
    },
    myValue (newValue) {
      this.$emit('input', newValue)
    }
  }
}

</script>
<style scoped>
</style>

注意:在普通页面中没有任何问题,但是在模态框中内,会产生层级问题,导致颜色、字体,省略功能无法实现。

下面使用的是element-ui的模态框,需要更改模态层级与遮罩层的层级。

Notice.vue

<template>
  <div class="content-warp">
    <div class="top-wrap">
      <div class="top-wrap_head head_input">
        <el-input size="small" v-model="title" placeholder="请输入标题" label="标题" clearable>
          <template slot="prepend">标题</template>
        </el-input>
      </div>
      <div class="head_btn">
        <el-button type="primary" size="mini" class="admin-btn" @click="query">查询</el-button>
        <el-button type="success" size="mini" class="admin-btn" @click="handleAdd">发布</el-button>
      </div>
    </div>
    <div class="table_content">
      <el-table
        ref="multipleTable"
        :data="notice_data"
        tooltip-effect="dark"
        style="width: 100%"
        @selection-change="handleSelectionChange"
        stripe
      >
        <el-table-column type="selection" width="60"></el-table-column>
        <el-table-column prop="key" label="序号" width="100"></el-table-column>
        <el-table-column prop="title" label="标题" width="300"></el-table-column>
        <el-table-column prop="desc" label="内容" align="center"></el-table-column>
        <el-table-column prop="read_num" label="已读数" width="100" align="center"></el-table-column>
        <el-table-column prop="time" label="添加时间" width="200" align="center"></el-table-column>
        <el-table-column label="操作">
          <template slot-scope="scope">
            <el-button
              size="mini"
              type="primary"
              plain
              @click="handleView(scope.$index, scope.row)"
            >查看
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        layout="prev, pager, next"
        :total="count"
        :page-size="n"
        @current-change="change">
      </el-pagination>
    </div>
    <el-dialog
      :title="dialogTitle"
      :visible="dialogFormVisible"
      width="40%"
      :destroy-on-close="true"
      :before-close="handleClose"
      :modal-append-to-body="false"
    >
      <el-form
        :model="notice_info"
        v-if="dialogTitle === '发布'"
        ref="notice_info"
      >
        <el-form-item label="通知标题" label-width="100px" prop="name">
          <el-input v-model="notice_info.title" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="通知内容" label-width="100px" prop="title_url">
          <TinymceEditor @onClick="onClick" v-model="notice_info.desc" ref="editor" :plugins="plugins"
                         :toolbar="toolbar" :disabled="disabled"></TinymceEditor>
        </el-form-item>
        <el-form-item label-width="100px">
          <el-button type="primary" @click="onSubmit('notice_info')">发布</el-button>
          <el-button @click="handleClose">取消</el-button>
          <el-button @click="clear">清空数据</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>

<script>
import qs from 'qs'
import TinymceEditor from '@/components/Common/tinymce-editor'

export default {
  components: {
    TinymceEditor
  },
  data () {
    return {
      title: '',
      p: 1,
      n: 10,
      count: 0,
      disabled: false,
      notice_data: [],
      handleSelectionChange: [],
      dialogFormVisible: false,
      dialogTitle: '',
      notice_info: {
        title: '',
        desc: ''
      },
      // 用于富文本编辑的插件
      plugins: 'lists table wordcount',
      // 用于头部菜单显示的插件
      toolbar: 'undo redo |  formatselect | bold italic forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | lists table '
    }
  },
  mounted () {
    this.get_data()
  },
  methods: {
    get_data () {
      this.$http.getNotices(this.title, this.p, this.n).then(res => {
        if (res.code === 200) {
          this.count = res.count
          this.notice_data = res.data.map((item, index) => {
            item['key'] = index + 1
            return item
          })
        }
      }).catch(err => {
        console.log(err, 'err')
      })
    },
    change (p) {
      this.p = p
      this.get_data()
    },
    query () {
      this.get_data()
    },
    handleView () {
      console.log('查看')
    },
    handleClose () {
      this.dialogFormVisible = false
    },
    handleAdd () {
      this.dialogFormVisible = true
      this.dialogTitle = '发布'
    },
    onSubmit (formName) {
      if (!this.notice_info.title || !this.notice_info.desc) {
        this.$message.error('请填写数据')
        return false
      }
      this.$refs[formName].validate(valid => {
        if (valid) {
          this.$http.postAddUpdateNotice(qs.stringify(this.notice_info)).then(res => {
            if (res.code === 200) {
              this.$message.success('添加成功')
              this.query()
              this.notice_info = {}
            }
          }).catch(err => {
            console.log(err, 'err')
          })
          this.dialogFormVisible = false
        } else {
          return false
        }
      })
    },
    onClick (e, editor) {
      console.log('Element clicked')
    },
    clear () {
      this.$refs.editor.clear()
    }
  }
}
</script>

<style scoped>
  .content-warp .el-dialog__wrapper {
    z-index: 200 !important;
  }

  .el-form {
    width: 700px !important;
  }
</style>
<style>
  .v-modal {
    z-index: 100 !important;
  }
</style>

相关文章

网友评论

      本文标题:vue-cli3集成tinymce5富文本

      本文链接:https://www.haomeiwen.com/subject/qyzuihtx.html