# wangEditor

houdunren.com (opens new window) @ 向军大叔

xj-small

wangEditor (opens new window)是优秀的国产富文本编辑器,下面我们来掌握在项目中集成上这款编辑器。

image-20201120231553289

# Laravel

下面将编辑器定义成laravel的组件方便在项目中调用。

# 后台业务

执行以下创建生成组件后台处理文件 app/View/Components/Editor.php(上面的tui.editor组件已经创建过)

php artisan make:component Editor

内容如下

<?php

namespace App\View\Components;

use Illuminate\View\Component;

class Editor extends Component
{
  public $theme;
  public $name;
  public $value;
  public $height;
  public $type;
  public $action;

  /**
   * 初始参数
   * @param string $theme 编辑器类型
   * @param mixed $name 表单名称
   * @param string $value 默认值
   * @return void
   */
  public function __construct($theme = 'wang', $name, $value = '', $height = 300, $type = 'markdown', $action = null)
  {
    $this->theme = $theme;
    $this->name = $name;
    $this->value = $value;
    $this->height = $height;
    $this->type = $type;
    $this->action = $action ?? route('common.upload.make');
  }

  public function validateName($name)
  {
    return str_replace(['[', ']'], ['.', ''], $name);
  }

  public function render()
  {
    return view('components.editor.' . $this->theme);
  }
}

# 组件模板

创建组件模板文件 resources/views/components/editor/wang.blade.php,内容如下

代码中使用了 @push 指定,所以需要在你项目中的父模板中使用 @stack('styles') 与 @stack('scripts')

<div id="wangEditor{{$name}}">
  <p>{!! $value !!}</p>
</div>
<textarea name="{{ $name }}" id="{{ $name }}Editor" hidden></textarea>

@error($validateName($name))
<strong class="form-text text-danger small font-weight-bold" id="{{ $name.'errors' }}">{{ $message }}</strong>
@enderror

@push('scripts')
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.min.js"></script>
<script type="text/javascript" src="//unpkg.com/wangeditor/dist/wangEditor.min.js"></script>
<script type="text/javascript">
  {
    const editor = new wangEditor("#wangEditor{{$name}}");
    editor.config.uploadImgServer = `{{$action?? route('common.upload.wangEditor') }}`
    editor.config.uploadImgMaxSize = 2 * 1024 * 1024
    editor.config.uploadImgMaxLength = 5
    editor.config.uploadFileName = 'file'
    editor.config.showLinkImg = false
    editor.config.debug = true
    editor.config.zIndex = 100
    editor.config.uploadImgHeaders = {
      'X-CSRF-TOKEN': document.querySelector("meta[name='csrf-token']").content,
      Accept: 'application/json',
    }
    const textarea = document.getElementById("{{ $name }}Editor");
    editor.config.onchange = (html)=> {
      //保存到表单中准备提交
      textarea.value = html
      //有输入时移除错误消息
      const errorEl = document.querySelector(`#{{$name}}errors`);
      if(errorEl) errorEl.remove();
    }
    editor.create()
    textarea.value = editor.txt.html()
  }
</script>
@endpush

# 使用组件

在模板中使用以下代码调用编辑器

<x-editor theme="wang" name="content" value="默认值-后盾人" height="300" action="/common/upload/make" />

下面来对属性进行说明

属性 说明
theme 值固定为wang
name 表单name
value 初始值
height 编辑器高度
action 后台图片上传地址

# vue

下面实现开发wangEditor的vue组件,首先安装扩展包

cnpm install wangeditor --save

# 组件代码

然后创建 HdWangEditor.vue组件文件

<template>
  <div :id="name"></div>
</template>

<script>
import wangEditor from 'wangEditor'
export default {
  props: {
    name: { type: String, default: 'editor' },
    uploadImgServer: { type: String, default: '/common/upload/wangEditor' },
    value: { type: String, default: '' },
  },

  data() {
    return {
      editor: null,
    }
  },
  watch: {
    value: {
      handler(n) {
        this.value = n
        if (this.editor) this.editor.txt.html(n)
      },
      immediate: true,
    },
  },
  mounted() {
    this.editor = new wangEditor('#editor')
    this.editor.customConfig.uploadImgServer = this.uploadImgServer
    this.editor.customConfig.uploadImgMaxSize = 3 * 1024 * 1024
    this.editor.customConfig.uploadImgMaxLength = 5
    this.editor.customConfig.uploadFileName = 'file'
    this.editor.customConfig.uploadImgHooks = this.uploadHandle
    this.editor.customConfig.showLinkImg = false
    this.editor.customConfig.debug = true
    this.editor.customConfig.onchange = this.updateContent
    this.editor.customConfig.zIndex = 100
    this.editor.customConfig.uploadImgHeaders = {
      'X-CSRF-TOKEN': document.querySelector("meta[name='csrf-token']").content,
      Accept: 'application/json',
    }
    this.editor.customConfig.menus = [
      'head', // 标题
      'bold', // 粗体
      'fontSize', // 字号
      'fontName', // 字体
      'italic', // 斜体
      'underline', // 下划线
      'strikeThrough', // 删除线
      'foreColor', // 文字颜色
      'backColor', // 背景颜色
      'link', // 插入链接
      'list', // 列表
      'justify', // 对齐方式
      'quote', // 引用
      //'emoticon', // 表情
      'image', // 插入图片
      'table', // 表格
      'video', // 插入视频
      'code', // 插入代码
      'undo', // 撤销
      'redo', // 重复
    ]
    this.editor.create()
  },
  methods: {
    updateContent(html) {
      this.$emit('update:value', this.editor.txt.html())
    },
    uploadHandle() {
      return {
        before: function (xhr, editor, files) {},
        success: function (xhr, editor, result) {},
        fail: function (xhr, editor, result) {},
        error: function (xhr, editor) {},
        timeout: function (xhr, editor) {},
        customInsert: function (insertImg, result, editor) {},
      }
    },
  },
}
</script>

<style lang="scss"></style>

# 使用方式

 <hd-wang-editor name="editor" :value.sync="current.content" action="/common/upload"></hd-wang-editor>

下面对属性进行说明

属性 说明
name 表单名称
value 默认值
action 图片上传地址

# 后台上传

后台需要返回以下数据结构

json_encode([
    'errno' => 0,
    'data' => ['1.jpeg'],
]);