记一次Vue使用WangEditor发表/编辑文章

使用npm下载:npm install wangeditor (注意 wangeditor 全部是小写字母)

<template>
  <div>
    <Template :titleName="titleName" :className="className">
      <!-- Form -->
      <div slot="tool">
        <Form :model="form" inline>
          <FormItem prop="articleTitle">
            <Input v-model="form.articleTitle" placeholder="请输入文章标题"></Input>
          </FormItem>
          <FormItem prop="articleAuther">
            <Input v-model="form.articleAuther" placeholder="请输入文章作者"></Input>
          </FormItem>
          <FormItem prop="articleStatus">
            <Select
              v-model="form.articleStatus"
              placeholder="请选择文章状态"
              clearable
              style="width:200px"
            >
              <Option
                v-for="item in articleStatusList"
                :value="item.value"
                :key="item.value"
              >{{ item.label }}</Option>
            </Select>
          </FormItem>
          <FormItem>
            <DatePicker
              type="daterange"
              split-panels
              placeholder="请输入文章创建时间"
              style="width: 200px"
              format="yyyy-MM-dd HH:mm:ss"
              @on-change="time"
            ></DatePicker>
          </FormItem>
          <FormItem>
            <Button type="primary" icon="ios-search" @click="searchHandle">搜 索</Button>
          </FormItem>
          <FormItem>
            <Button
              type="success"
              icon="md-brush"
              @click="createArticleHandle"
              v-if="access.includes('article:create')"
            >新增文章</Button>
          </FormItem>
        </Form>
      </div>
      <!-- Table -->
      <div slot="content">
        <Table
          border
          :columns="tableColumn"
          :height="tableHeight"
          :highlight-row="true"
          :data="tableData"
          :loading="tableLoading"
        >
          <template
            slot-scope="{row}"
            slot="businessPriceSlot"
            v-if="access.includes('article:viewPrice')"
          >
            <span
              v-text="row.businessVo.business4PriceVo.businessPrice===undefined?'':'¥'+row.businessVo.business4PriceVo.businessPrice.toFixed(3)*1000/1000"
            ></span>
          </template>
          <template
            slot-scope="{row}"
            slot="totalBusinessPriceSlot"
            v-if="access.includes('article:viewPrice')"
          >
            <span
              v-text="row.businessVo.business4PriceVo.businessPrice===undefined || row.articleChannelPageViews===undefined?'':
              '¥'+(row.businessVo.business4PriceVo.businessPrice.toFixed(3)*row.articleChannelPageViews.toFixed(3)).toFixed(3)*1000/1000"
            ></span>
          </template>
          <template
            slot-scope="{row}"
            slot="businessNameSlot"
          >{{row.businessVo.business4PriceVo.businessName}}</template>
          <template slot-scope="{row}" slot="articleLink">
            <a :href="host+row.articleId" target="_blank">{{row.articleTitle}}</a>
          </template>
          <template slot-scope="{ row }" slot="articleStatus">
            <Tag v-if="0 === row.articleStatus" color="green">草稿</Tag>
            <Tag v-if="1 === row.articleStatus" color="magenta">已发布</Tag>
            <Tag v-if="2 === row.articleStatus" color="volcano">已撤销</Tag>
          </template>
          <template slot-scope="{ index, row }" slot="action">
            <Tooltip content="编辑" placement="top" v-if="access.includes('article:update')">
              <Button
                type="info"
                icon="ios-create-outline"
                size="small"
                @click="updateArticleHandle(index, row)"
              ></Button>
            </Tooltip>

            <Tooltip content="预览文章" placement="top" v-if="access.includes('article:view')">
              <Button
                type="primary"
                size="small"
                icon="md-eye"
                ghost
                @click="lookArticleHandle(index, row)"
              ></Button>
            </Tooltip>
            <Tooltip
              v-if="0!==row.articleStatus && access.includes('article:updateStatus')"
              :content="2!==row.articleStatus?'撤销':'恢复'"
              placement="top"
            >
              <Button
                :type="2!==row.articleStatus?'warning':'primary'"
                size="small"
                :icon="2!==row.articleStatus?'md-eye-off':'md-refresh'"
                @click="isWithdrawArticle(index, row)"
              ></Button>
            </Tooltip>
            <Tooltip content="删除" placement="top" v-if="access.includes('article:delete')">
              <Button
                type="error"
                size="small"
                icon="md-trash"
                @click="removeArticleHandle(index, row)"
              ></Button>
            </Tooltip>
            <Tooltip content="设置浏览量" placement="top" v-if="access.includes('article:setPageViews')">
              <Button
                type="success"
                ghost
                size="small"
                icon="md-create"
                @click="setArticleViewsHandle(index, row)"
              ></Button>
            </Tooltip>
            <Tooltip
              content="修改文章投放渠道"
              placement="top"
              v-if="access.includes('article:updateChannel')"
            >
              <Button
                type="success"
                size="small"
                icon="ios-add-circle-outline"
                @click="setArticleChannelHandle(index, row)"
              ></Button>
            </Tooltip>
          </template>
        </Table>
      </div>
      <!-- Tool -->
      <div slot="foot">
        <Page
          :total="total"
          show-elevator
          :page-size="form.size"
          :page-size-opts="pageSizeOpts"
          show-total
          @on-change="pageChangeHandle"
        />
      </div>
    </Template>

    <ArticleModal ref="articleModal" @create="createArticleSuccess" @update="updateArticleSuccess"></ArticleModal>
    <ArticlePreview ref="articlePreview"></ArticlePreview>
    <ArticleViewsModal ref="articleViewsModal" @success="setArticleViewsSuccessHandle" />
    <ArticleChannelModal ref="articleChannelModal" @success="setArticleChannelSuccessHandle" />
  </div>
</template>

<script>
import Template from "@/components/page/page-templete";
import ArticleModal from "./article-modal";
import expandRow from "./table-expand.vue";
import ArticlePreview from "./article-preview";
import ArticleViewsModal from "./article-view-set-modal";
import ArticleChannelModal from "./article-add-channel-modal";

import {
  queryArticleList,
  deleteArticle,
  withdrawArticle,
  queryBusinessList
} from "@/api/article";
import { responseHandle } from "@/libs/util";
import { listChannelsApi } from "@/api/channel";
export default {
  components: {
    Template,
    ArticleModal,
    expandRow,
    ArticlePreview,
    ArticleViewsModal,
    ArticleChannelModal
  },
  data() {
    return {
      host: "http://" + window.location.host + "/article?id=",
      titleName: "文章管理",
      className: "article",
      businessList: [],
      channelList: [],
      viewForm: {
        articleId: "",
        articlePageViews: ""
      },
      form: {
        articleTitle: "",
        articleAuther: "",
        articleStatus: "",
        current: 1,
        size: 15
      },
      tableHeight: 550,
      tableLoading: true,
      tableColumn: [
        {
          type: "expand",
          width: 50,
          render: (h, params) => {
            return h(expandRow, {
              props: {
                row: params.row
              }
            });
          }
        },
        // { title: "编号", key: "articleId" },
        {
          title: "标题",
          slot: "articleLink"
        },
        {
          title: "作者",
          key: "articleAuther"
        },
        {
          title: "商户名称",
          slot: "businessNameSlot"
        },
        {
          title: "标签",
          key: "articleLalbel"
        },
        // {
        //   title: "浏览量",
        //   slot: "articlePageViewsSlot",
        //   align: "center"
        // },

        {
          title: "浏览量",
          key: "articlePageViews"
        },
        {
          title: "渠道总浏览量",
          key: "articleChannelPageViews"
        },
        {
          title: "单价",
          slot: "businessPriceSlot"
        },
        {
          title: "总价",
          slot: "totalBusinessPriceSlot"
        },
        // {
        //   title: "渠道总浏览量",
        //   slot: "articleChannelPageViewsSlot",
        //   align: "center"
        // },
        {
          title: "状态",
          slot: "articleStatus"
        },
        {
          title: "操  作",
          slot: "action",
          width: 330,
          align: "left"
        }
      ],
      tableData: [],
      total: 0,
      pageSizeOpts: [15, 30, 50],
      rowIndex: -1,
      balanceFormModalStatus: false,
      balanceFormLoading: true,
      articleStatusList: [
        {
          value: "0",
          label: "草稿"
        },
        {
          value: "1",
          label: "已发布"
        },
        {
          value: "2",
          label: "已撤销"
        }
      ],
      articleStatus: ""
    };
  },
  computed: {
    access() {
      return this.$store.state.user.access;
    }
  },
  mounted() {
    this.hideTableColumnHeader4Business()
    this.tableHeight = window.innerHeight - 315;
    this.loadArticleList(false);
    this.loadBusinessList();
    this.loadChannelList();
  },
  methods: {
    hideTableColumnHeader4Business() {
      if (!this.access.includes("article:viewPrice")) {
        for (var i in this.tableColumn) {
          if (this.tableColumn[i].title === "单价") {
            this.tableColumn.splice(i, 1);
          }
          if (this.tableColumn[i].title === "总价") {
            this.tableColumn.splice(i, 1);
          }
        }
      }
    },
    loadChannelList() {
      responseHandle(this, listChannelsApi, null, false)
        .then(({ status, data }) => {
          if (status === 200) {
            this.channelList = data;
          }
        })
        .catch(e => {
          this.resetLoading();
        });
    },
    setArticleChannelHandle(index, row) {
      this.$refs.articleChannelModal.open(index, row, this.channelList);
    },
    setArticleChannelSuccessHandle(index, data) {
      // this.$set(this.tableData, index, data);
      this.loadArticleList(false);
    },
    setArticleViewsHandle(index, row) {
      this.$refs.articleViewsModal.open(index, row);
    },
    setArticleViewsSuccessHandle(index, data) {
      // var oldData = { ...this.tableData[index] };
      // this.$set(data, "channelVo", oldData.channelVo);
      // this.$set(this.tableData, index, data);
      this.loadArticleList(false);
    },
    loadBusinessList() {
      responseHandle(this, queryBusinessList, null, false)
        .then(({ status, data }) => {
          if (status === 200) {
            this.businessList = data;
          }
        })
        .catch(() => {});
    },
    time(val) {
      this.form.startTime = val[0];
      this.form.endTime = val[1];
    },
    loadArticleList(param) {
      var showMessage = param ? true : param;
      this.tableLoading = true;
      responseHandle(this, queryArticleList, this.form, showMessage)
        .then(({ status, data }) => {
          if (status === 200) {
            this.tableData = data.records;
            this.total = data.total;
          }
          this.tableLoading = false;
        })
        .catch(() => {
          this.tableLoading = false;
        });
    },
    searchHandle() {
      this.form.current = 1;
      this.loadArticleList();
    },
    //新增文章
    createArticleHandle() {
      this.rowIndex = -1;
      this.$refs.articleModal.open(0, "", this.businessList);
    },
    createArticleSuccess(data) {
      this.tableData.unshift(data);
      // this.loadArticleList();
    },
    updateArticleSuccess(data) {
      // var oldRowData = { ...this.tableData[this.rowIndex] };
      // this.$set(data, "channelVo", oldRowData.channelVo);
      // this.$set(data, "businessVo", oldRowData.businessVo);
      // this.tableData.splice(this.rowIndex, 1, data);
      this.loadArticleList(false);
    },
    //修改文章
    updateArticleHandle(index, row) {
      this.rowIndex = index;
      this.$refs.articleModal.open(1, row, this.businessList);
    },
    //查看文章详情
    lookArticleHandle(index, row) {
      this.rowIndex = index;
      this.$refs.articlePreview.open(row);
    },
    pageChangeHandle(page) {
      this.form.current = page;
      this.loadArticleList();
    },
    isWithdrawArticle(index, row) {
      this.$Modal.confirm({
        title: "警  告",
        content: `确认要${
          row.articleStatus === 2 ? "恢复" : "撤销"
        } <span class="confirm-keyword">${row.articleTitle}</span> 吗?`,
        onOk: () => {
          withdrawArticle(row.articleId)
            .then(({ status, message, data }) => {
              if (status === 200) {
                // this.loadArticleList();
                this.$set(
                  data,
                  "articleChannelPageViews",
                  row.articleChannelPageViews
                );
                this.$set(data, "businessVo", row.businessVo);
                this.$set(data, "channelVo", row.channelVo);
                this.tableData.splice(index, 1, data);
                this.$Message["success"]({
                  background: true,
                  content: message || "操作成功",
                  duration: 2.5
                });
              } else {
                this.$Notice.error({
                  title: message,
                  desc: data ? `• ${data}` : "• 操作失败"
                });
              }
            })
            .catch(e => {
              this.$Message["error"]({
                background: true,
                content: e && e.message ? e.message : "操作失败",
                duration: 2.5
              });
            });
        }
      });
    },
    removeArticleHandle(index, row) {
      this.$Modal.confirm({
        title: "警  告",
        content: `确认要删除 <span class="confirm-keyword">${"文章:" +
          row.articleTitle}</span> 吗?`,
        onOk: () => {
          deleteArticle(row.articleId)
            .then(({ status, message, data }) => {
              if (status === 200) {
                this.loadArticleList();
                // this.$Message["success"]({
                //   background: true,
                //   content: message,
                //   duration: 2.5
                // });
              } else {
                this.$Notice.error({
                  title: message,
                  desc: `• ${data}`
                });
              }
            })
            .catch(e => {
              this.$Message["error"]({
                background: true,
                content: e && e.message ? e.message : "操作失败",
                duration: 2.5
              });
            });
        }
      });
    }
  }
};
</script>

<style>
.confirm-keyword {
  color: red;
  font-weight: bold;
}
.ivu-tooltip {
  margin-left: 5px;
}
</style>
article.vue组件
<template>
  <Modal
    v-model="show"
    :title="title"
    :mask-closable="false"
    :loading="modalLoading"
    :width="50"
    @on-ok="ok"
    @on-cancel="cancel"
  >
    <Form
      ref="articleForm"
      :model="form"
      :label-width="80"
      :rules="ruleValidate"
      class="article-form"
      :disabled="onlyRead"
      :label-colon="true"
    >
      <FormItem label="商户" prop="businessId">
        <Select v-model="form.businessId" placeholder="请选择与文章关联的商户" filterable>
          <Option
            v-for="item in businessList"
            :value="item.businessId"
            :key="item.businessId"
          >{{ item.businessName }}</Option>
        </Select>
      </FormItem>
      <FormItem label="标题" prop="articleTitle">
        <Input v-model="form.articleTitle" placeholder="请输入标题"></Input>
      </FormItem>
      <FormItem label="作者" prop="articleAuther">
        <Input v-model="form.articleAuther" placeholder="请输入作者"></Input>
      </FormItem>

      <FormItem label="标签" prop="labelTextArr">
        <Tag
          v-for="item in labelTextArr"
          :key="item"
          :name="item"
          closable
          @on-close="handleClose2"
        >{{item}}</Tag>

        <Button icon="ios-add" type="dashed" size="small" @click="handleAdd">添加标签</Button>
      </FormItem>

      <FormItem label="内容" prop="articleContent">
        <weang-editor :onlyRead="onlyRead" :content="text" :catchData="catchData"></weang-editor>
      </FormItem>
      <FormItem>
        <Button v-if="this.type===0 || this.type===1 " @click="saveToDraft">保存为草稿</Button>
      </FormItem>
    </Form>

    <Modal v-model="isShow" title="请输入文章标签" @on-ok="labelOk" @on-cancel="labelCancel">
      <Input v-model="articleLalbel" placeholder="请输入一个文章标签"></Input>
    </Modal>
  </Modal>
</template>

<script>
import { saveArticle } from "@/api/article";
import { responseHandle } from "@/libs/util";
import weangEditor from "./wangEditor";
export default {
  components: {
    "weang-editor": weangEditor
  },
  data() {
    return {
      type: 0,
      onlyRead: false,
      articleLalbel: null,
      isShow: false,
      labelTextArr: [],
      show: false,
      title: "",
      text: "",
      modalLoading: true,
      businessList: [],
      form: {
        articleId: "",
        articleTitle: "",
        articleAuther: "",
        articleLalbel: "",
        articleContent: "",
        articleStatus: "",
        businessId: ""
      },
      ruleValidate: {
        businessId: [
          {
            required: true,
            message: "与文章关联的商户不能为空",
            trigger: "blur"
          }
        ],
        articleTitle: [
          { required: true, message: "标题不能为空", trigger: "blur" },
          {
            type: "string",
            min: 1,
            max: 100,
            message: "标题长度需要在1和100之间",
            trigger: "blur"
          }
        ],
        articleAuther: [
          { required: true, message: "作者不能为空", trigger: "blur" },
          {
            type: "string",
            min: 1,
            max: 20,
            message: "作者长度需要在1和20之间",
            trigger: "blur"
          }
        ],
        articleContent: [
          {
            required: true,
            message: "文章内容不能为空",
            trigger: "blur"
          }
        ]
      }
    };
  },
  methods: {
    saveToDraft() {
      this.form.articleStatus = 0;
      this.ok();
    },
    catchData(html) {
      this.form.articleContent = html;
    },
    labelOk() {
      if (this.articleLalbel !== null) {
        const index = this.labelTextArr.indexOf(this.articleLalbel);
        if (this.labelTextArr.length > 4) {
          this.$Message.warning("标签数量不能超过5个");
          return;
        }
        if (this.articleLalbel.length > 10) {
          this.$Message.warning("标签长度不能超过10");
          this.articleLalbel = null;
          return;
        }
        if (index > -1) {
          this.$Message.warning("标签【" + this.articleLalbel + "】已存在");
        } else {
          this.labelTextArr.push(this.articleLalbel);
        }
        this.articleLalbel = null;
      }
      // this.$Message.info("Clicked ok");
    },
    labelCancel() {
      // this.$Message.info("Clicked cancel");
    },
    handleAdd() {
      this.isShow = true;
    },
    handleClose2(event, name) {
      if (this.onlyRead) {
        return;
      }
      const index = this.labelTextArr.indexOf(name);
      this.labelTextArr.splice(index, 1);
    },
    open(type, article, businessList) {
      this.onlyRead = false;
      this.form.articleStatus = "";
      this.type = type;
      if (0 === type) {
        this.title = "新增文章";
        this.text = "<p></p>";
        this.businessList = businessList;
      } else if (1 === type) {
        this.title = "修改文章";
        const {
          articleTitle,
          articleAuther,
          articleContent,
          articleId
        } = article;
        const { businessId } = article.businessVo;
        this.businessList = businessList;
        this.text = article.articleContent;
        this.form = {
          articleTitle,
          articleAuther,
          articleContent,
          articleId,
          businessId
        };
        //回显标签
        if (article.articleLalbel !== "") {
          this.labelTextArr = article.articleLalbel.split(",");
        }
      } else {
        //查看文章详情
        this.title = "文章详情";
        this.onlyRead = true;
        this.text = article.articleContent;
        const { articleTitle, articleAuther, articleContent } = article;
        this.form = { articleTitle, articleAuther, articleContent };
        //回显标签
        if (article.articleLalbel !== "") {
          this.labelTextArr = article.articleLalbel.split(",");
        }
      }

      this.show = true;
    },
    close() {
      this.onlyRead = false;
      this.$refs["articleForm"].resetFields();
      this.show = false;
      this.labelTextArr = [];
    },
    ok() {
      this.$refs["articleForm"].validate(valid => {
        if (this.type === 0) {
          //新增
          if (valid) {
            //数组转字符串
            this.form.articleLalbel = this.labelTextArr.toString();
            responseHandle(this, saveArticle, this.form)
              .then(({ status, data }) => {
                if (200 === status) {
                  this.$emit("create", data);
                  this.close();
                }
                this.resetLoading();
              })
              .catch(() => {
                this.resetLoading();
              });
          } else {
            this.$Message.error("表单填写有误");
            this.resetLoading();
          }
        }
        if (this.type === 1) {
          //编辑
          if (valid) {
            //数组转字符串
            this.form.articleLalbel = this.labelTextArr.toString();
            responseHandle(this, saveArticle, this.form)
              .then(({ status, data }) => {
                if (200 === status) {
                  this.$emit("update", data);
                  this.close();
                }
                this.resetLoading();
              })
              .catch(() => {
                this.resetLoading();
              });
          } else {
            this.$Message.error("表单填写有误");
            this.resetLoading();
          }
        }
        if (this.type === 2) {
          //查看
          this.close();
        }
      });
    },
    cancel() {
      this.close();
    },
    resetLoading() {
      this.modalLoading = false;
      this.$nextTick(() => {
        this.modalLoading = true;
      });
    }
  }
};
</script>

<style>
.article-form {
  padding-right: 12px;
}
.ivu-input[disabled],
fieldset[disabled] .ivu-input {
  color: #aaacb1;
}
.ivu-select-selected-value {
  color: #aaacb1;
}
</style>
article-modal.vue 主要是创建/编辑 用到的组件
<template>
  <div id="wangeditor">
    <div ref="editorElem" style="text-align:left;"></div>
  </div>
</template>

<script>
import E from "wangeditor";
export default {
  name: "Editor",
  data() {
    return {
      editor: null
    };
  },
  // catchData是一个类似回调函数,来自父组件,当然也可以自己写一个函数,主要是用来获取富文本编辑器中的html内容用来传递给服务端
  props: ["catchData", "onlyRead", "content"], // 接收父组件的方法
  mounted() {
    this.editor = new E(this.$refs.editorElem);
    // 编辑器的事件,每次改变会获取其html内容
    this.editor.customConfig.onchange = html => {
      this.catchData(html); // 把这个html通过catchData的方法传入父组件
    };

    this.editor.customConfig.menus = [
      // 菜单配置
      "head", // 标题
      "bold", // 粗体
      "fontSize", // 字号
      "fontName", // 字体
      "italic", // 斜体
      "underline", // 下划线
      "strikeThrough", // 删除线
      "foreColor", // 文字颜色
      "backColor", // 背景颜色
      "link", // 插入链接
      "list", // 列表
      "justify", // 对齐方式
      // "quote", // 引用
      // "emoticon", // 表情
      "image", // 插入图片
      "table", // 表格
      "code", // 插入代码
      "undo", // 撤销
      "redo" // 重复
    ];
    //显示本地上传图片Tab
    // this.editor.customConfig.uploadImgShowBase64 = true;
    //隐藏网络图片Tab
    this.editor.customConfig.showLinkImg = false;
    //限制一次最多能传几张图片
    this.editor.customConfig.uploadImgMaxLength = 10;
    // this.editor.customConfig.onchange = function (html) {
    //     // html 即变化之后的内容
    //     console.log(html)
    //     this.$emit('catchData',html)
    // }
    //  this.editor.customConfig.uploadImgShowBase64 = false
    this.editor.customConfig.uploadImgServer = "/api/pictrues";
    // 将图片大小限制为 3M
    this.editor.customConfig.uploadImgMaxSize = 3 * 1024 * 1024;
    // 跨域上传中如果需要传递 cookie 需设置 withCredentials
    this.editor.customConfig.withCredentials = true;
    // 将 timeout 时间改为 3s
    // this.editor.customConfig.uploadImgTimeout = 3000;

    this.editor.customConfig.debug = true;
    this.editor.customConfig.uploadFileName = "file"; //上传参数 自定义
    this.editor.customConfig.uploadImgHooks = {
      before: function(xhr, editor, files) {
        // 图片上传之前触发
        // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,files 是选择的图片文件
        // 如果返回的结果是 {prevent: true, msg: 'xxxx'} 则表示用户放弃上传
        // return {
        //     prevent: true,
        //     msg: '放弃上传'
        // }
      },
      success: function(xhr, editor, result) {
        // 图片上传并返回结果,图片插入成功之后触发
        // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果
      },
      fail: function(xhr, editor, result) {
        // 图片上传并返回结果,但图片插入错误时触发
        this.$message("图片插入错误");
        // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果
      },
      error: function(xhr, editor) {
        // 图片上传出错时触发
        this.$message("图片上传出错");
        // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象
      },
      timeout: function(xhr, editor) {
        // 图片上传超时时触发
        this.$message("上传图片超时");
        // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象
      }

      // 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置
      // (但是,服务器端返回的必须是一个 JSON 格式字符串!!!否则会报错)
      // customInsert: function(insertImg, result, editor) {
      //   // 图片上传并返回结果,自定义插入图片的事件(而不是编辑器自动插入图片!!!)
      //   // insertImg 是插入图片的函数,editor 是编辑器对象,result 是服务器端返回的结果

      //   // 举例:假如上传图片成功后,服务器端返回的是 {url:'....'} 这种格式,即可这样插入图片:
      //   for (var i = 0; i < result.data.length; i++) {
      //     debugger
      //     insertImg(result.data[i]);
      //   }
      // result 必须是一个 JSON 格式字符串!!!否则报错
      // }
    };
    this.editor.create(); // 创建富文本实例

    //禁用编辑器
    // this.editor.$textElem.attr('contenteditable',false);
  },
  watch: {
    onlyRead(val, oldVal) {
      val
        ? this.editor.$textElem.attr("contenteditable", false)
        : this.editor.$textElem.attr("contenteditable", true);
    },
    content(val) {
      this.editor.txt.html(val);
    }
  }
};
</script>
wangEditor.vue 富文本编辑框

更多Api以及使用方法请访问wangEditor文档:https://www.kancloud.cn/wangfupeng/wangeditor3/332599

猜你喜欢

转载自www.cnblogs.com/song1024/p/12517808.html