先上一波效果图
在这里插入图片描述
官方文档 中文版 http://tinymce.ax-z.cn/
官方文档 英文版 https://www.tiny.cloud/docs/configure/accessibility/
github地址 https://github.com/MrH-OS/plugins_vue/tree/master/

说一下项目需求,首先引入 tinymce编辑器,然后在工具栏里面添加一个功能按钮,点击按钮出现弹窗,显示两个下拉框,并且这两个下拉框是联动的,即左侧下拉框选中一个表名,右侧下拉框根据左侧选中的表名,显示该表下的字段(表跟表之间联动是重点),并且是这两个下拉框均可以远程搜索,点击弹窗的保存按钮后,拼接的字段显示在鼠标点击的位置

一、引入tinymce

npm install tinymce -S

二、封装tinymce组件

html部分
在这里插入图片描述

js部分
在这里插入图片描述
在这里插入图片描述

代码如下

<!-- tinymce富文本编辑器组件 -->
<template>
  <div>
    <editor v-model="content" :value="value" :init="config" :disabled="disabled" />
    <!-- 弹窗组件 -->
    <el-dialog title="赋值" :visible.sync="showEdit" width="600px" @closed="form={}" :destroy-on-close="true" :lock-scroll="false" :append-to-body="true">
      <el-form :model="form" ref="editForm" :rules="rules" label-width="120px" :inline="true">      
        <el-form-item label="选择模块:" prop='mold'>
         <!-- filterable属性 可以实现远程搜索 -->
          <el-select v-model="form.mold" filterable style="width: 130px" placeholder="选择模块" @change="chooseMold($event)">       
            <el-option v-for="(item,index) in moldslist" :key="index" :label="item.name" :value="item.molds">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="所属模块字段:" prop="field">
          <el-select v-model="form.field" style="width: 130px" filterable placeholder="选择字段">
            <el-option v-for="(item,index) in fieldslist" :key="index" :label="item.name" :value="item.fields">
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="showEdit=false">取消</el-button>
        <el-button type="primary" @click="save">保存</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import tinymce from 'tinymce/tinymce'
import Editor from '@tinymce/tinymce-vue'
import 'tinymce/icons/default'
import 'tinymce/themes/silver'
import 'tinymce/plugins/code'
import 'tinymce/plugins/print'
import 'tinymce/plugins/preview'
import 'tinymce/plugins/fullscreen'
import 'tinymce/plugins/paste'
import 'tinymce/plugins/searchreplace'
import 'tinymce/plugins/save'
import 'tinymce/plugins/autosave'
import 'tinymce/plugins/link'
import 'tinymce/plugins/autolink'
import 'tinymce/plugins/image'
import 'tinymce/plugins/imagetools'
import 'tinymce/plugins/media'
import 'tinymce/plugins/table'
import 'tinymce/plugins/codesample'
import 'tinymce/plugins/lists'
import 'tinymce/plugins/advlist'
import 'tinymce/plugins/hr'
import 'tinymce/plugins/charmap'
import 'tinymce/plugins/emoticons'
import 'tinymce/plugins/anchor'
import 'tinymce/plugins/directionality'
import 'tinymce/plugins/pagebreak'
import 'tinymce/plugins/quickbars'
import 'tinymce/plugins/nonbreaking'
import 'tinymce/plugins/visualblocks'
import 'tinymce/plugins/visualchars'
import 'tinymce/plugins/wordcount'
import 'tinymce/plugins/emoticons/js/emojis'

export default {
  name: 'TinymceEditor',
  components: { Editor },
  model: {
    prop: 'value',
    event: 'change',
  },
  props: {
    value: String,
    init: Object,
    disabled: Boolean,
  },
  data() {
    return {
      content: '',
      moldslist: [], //模块列表
      showEdit: false, // 是否显示表单弹窗
      form: {}, // 表单数据
      rules: {
        // 表单验证规则
        mold: [{ required: true, message: '请选择mold表名', trigger: 'blur' }],
        field: [
          { required: true, message: '请输入field字段', trigger: 'blur' },
        ],
      },
      fieldslist: [], //fields字段列表
      loading: false, // 加载状态
      mold_field: '',
      myEditor: null, //定义editor的全局变量
      config: Object.assign(
        {
          height: 300,
          branding: false,
          skin_url: '/tinymce/skins/ui/oxide',
          content_css: '/tinymce/skins/content/default/content.css',
          language_url: '/tinymce/langs/zh_CN.js',
          language: 'zh_CN',
          plugins:
            'code print preview fullscreen paste searchreplace save autosave link autolink image imagetools media table codesample lists advlist hr charmap emoticons anchor directionality pagebreak quickbars nonbreaking visualblocks visualchars wordcount',
          toolbar:
            'fullscreen preview code | undo redo | forecolor backcolor | bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | formatselect fontselect fontsizeselect | link image media emoticons charmap anchor pagebreak codesample | ltr rtl | assignment',	//加入定义的按钮名到工具栏
          toolbar_drawer: 'sliding',
          images_upload_handler: (blobInfo, success, error) => {
            let file = blobInfo.blob()
            // 使用axios上传
            const formData = new FormData()
            formData.append('file', file, file.name)
            this.$http
              .post('/upload/uploadImage', formData)
              .then((res) => {
                if (res.data.code == 0) {
                  success(res.data.data)
                } else {
                  error(res.data.msg)
                }
              })
              .catch((e) => {
                console.error(e)
                error(e.message)
              })
          },
          //images_upload_handler: (blobInfo, success) => {
          //console.log(blobInfo)
          //success('data:image/jpeg;base64,' + blobInfo.base64());
          //},
          file_picker_types: 'media',
          file_picker_callback: () => {},
          setup: (editor) => {
            let _this = this
            _this.myEditor = editor
            //定义一个名为 assignment 的toolbar
            editor.ui.registry.addButton('assignment', {
              text: `<i class="el-icon-position" style="font-size: 18px"></i>`,
              tooltip: '赋值',
              onAction: () => {
                _this.showEdit = true
              },
            })
          },
        },
        this.init
      ),
    }
  },
  methods: {
    //获得所有模块数据
    getmoldslist() {
      this.$http
        .get('/molds/getmyall?nouser=1')
        .then((res) => {
          if (res.data.code === 0) {
            this.moldslist = res.data.data
          } else {
            this.$message.error(res.data.msg)
          }
        })
        .catch((e) => {
          this.$message.error(e.message)
        })
    },
    //选择模块时触发的事件
    chooseMold(val) {
      if (val != null && val != '') {
        // console.log(val)
        this.$http
          .get('/fields/getmyall?molds=' + val.toString())
          .then((res) => {
            if (res.data.code === 0) {
              this.fieldslist = res.data.data
              // console.log(this.fieldslist)
            } else {
              this.$message.error(res.data.msg)
            }
          })
          .catch((e) => {
            this.$message.error(e.message)
          })
      }
    },
    //保存模块选中的值
    save() {
      let _this = this
      this.$refs['editForm'].validate((valid) => {
        if (valid) {
          _this.showEdit = false
          //将模块名和字段名拼接,格式:模块名_字段名
          _this.mold_field ='#' + _this.form.mold + '_' + _this.form.field + '#'
          console.log(_this.mold_field)
          _this.myEditor.insertContent(_this.mold_field)
        } else {
          return false
        }
      })
    },
  },
  mounted() {
    tinymce.init({})
    this.getmoldslist()
  },
  watch: {
    content() {
      this.$emit('change', this.content)
    },
    value() {
      this.content = this.value
    },
  },
}
</script>

<style>
body .tox-tinymce-aux {
  z-index: 19892000;
}
</style>

三、使用封装的tinymce组件

在这里插入图片描述
在这里插入图片描述

Logo

前往低代码交流专区

更多推荐