首页 > 其他分享 >vue-quill-editor富文本编辑器

vue-quill-editor富文本编辑器

时间:2023-10-13 19:32:06浏览次数:36  
标签:文本编辑 vue false val views data dataForm editor true

安装npm vue-quill-editor

npm install vue-quill-editor --save

引入main.js文件里

// 字典标签组件
import quillEditors from "./components/quillEditor/index";
// 注册全局容器
Vue.component("quillEditors", quillEditors); //富文本框

文件目录预览

vue-quill-editor富文本编辑器_quillEditor

openai的chatgpt描述

一个表单项,其中包含了一个富文本编辑器组件 quillEditors 和一个判断数据是否请求完毕的 flag。当 flag 为 true 时,渲染富文本编辑器组件,同时可以进行编辑操作;当 flag 为 false 时,渲染已有的内容并且不能进行编辑操作。同时,使用了 Vue 的条件渲染指令 v-if 控制视图的显示与隐藏。


form表单的新增编辑其中一个字段用到了富文本编辑器

vue-quill-editor富文本编辑器_npm_02

注意编辑的时候要用v-if一个变量判断是否请求到数据,否则quillEditors编辑的时候框里面是空的

<-- views:查看新增编辑 flag获取到编辑的内容 -->

		flag: false,//数据是否请求完毕
    init(id,views) {
      this.flag = false;//默认设置为false 不显示quillEditors
      console.log('views', id, views);
      if (views == 1) {
        this.views = true;
        this.canSubmit = false;
      } else {
        this.views = false;
        this.canSubmit = true;
      }
      this.dataForm.mailTemplateId = id || '';

      this.dataForm.content = "";
      this.dataForm.name = "";
      this.visible = true;
      this.$nextTick(() => {
        this.$refs['dataForm'].resetFields()

        if (this.dataForm.mailTemplateId) {
          getObj(this.dataForm.mailTemplateId).then((response) => {
            this.dataForm = response.data.data;
            this.flag = true;//接口请求成功设置为true 显示quillEditors
          })
        } else {
          this.flag = true;接口没有请求也设置为true 显示quillEditors
        }
      })
    },

<el-form-item label="模板内容" prop="content">
	<!--新增编辑-->
	<div v-if="!views">
		<quillEditors class="ql-editor" v-if="flag" :disabled="views" :content="dataForm.content"
				@changeContent="changeContent"/>
	</div>

	<!--查看-->
	<div v-html="dataForm.content" v-if="views && dataForm.mailTemplateId"></div>
</el-form-item>


全部代码

list列表页

vue-quill-editor富文本编辑器_npm_03

<template>
  <div class="mod-config ml10">
    <!--搜索-->
    <div class="search searchHead" v-show="showSearch">
      <el-form ref="searchForm" :model="searchForm" :inline="true" size="mini">
        <el-form-item label="申请时间" prop="timeArray">
          <el-date-picker style="width: 360px" type="daterange" range-separator="至" v-model.trim="timeArray"
                          value-format="yyyy-MM-dd hh:mm:ss" start-placeholder="申请开始时间" end-placeholder="申请结束时间" size="small"
                          @change="timeArrayChange"></el-date-picker>
        </el-form-item>
        <el-form-item label="是否启用" prop="enableStatus">
          <el-select
            v-model="searchForm.enableStatus"
            clearable
            placeholder="请选择是否启用"
            size="small"
          >
            <el-option label="关闭" :value="0"></el-option>
            <el-option label="开启" :value="1"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button icon="el-icon-search" type="primary" size="small" @click="handleQuery">搜索</el-button>
          <el-button icon="el-icon-delete" size="small" @click="resetQuery">清空</el-button>
        </el-form-item>
      </el-form>
    </div>
    <div class="tableContent">
      <!--搜索刷新-->
      <toolbar @refreshTable="getDataList" :showSearch.sync="showSearch">
        <el-button slot="add" type="primary" icon="el-icon-plus" size="small" @click="addOrUpdateHandle()">新增模板</el-button>
      </toolbar>

      <div class="avue-crud">
        <el-table
            :data="dataList"
            border
            :default-sort = "{prop: 'createTime', order: 'descending'}"
            v-loading="dataListLoading">
          <el-table-column label="序号" align="left" min-width="50px" width="50">
            <template slot-scope="scope">
              {{ helper.generateIndex(scope.$index, searchForm) }}
            </template>
          </el-table-column>
          <el-table-column
              prop="name"
              header-align="left"
              align="left"
              label="模板名称">
          </el-table-column>

          <el-table-column
            align="center"
            label="是否启用"
            prop="enableStatus"
            width="150"
          >
            <template slot-scope="{ row }">

              <el-switch
                v-if="permissions.service_mailtemplate_edit"
                class="eval-switch"
                v-model="row.enableStatus"
                :active-value="1"
                :inactive-value="0"
                disabled
                @click.native="switchChange(row)"
              >
              </el-switch>

              <template v-else>
                <el-tooltip effect="dark" content="无此权限" placement="top">
                  <el-switch
                    v-model="row.enableStatus"
                    :active-value="1"
                    :inactive-value="0"
                    disabled
                  >
                  </el-switch>
                </el-tooltip>
              </template>
            </template>
          </el-table-column>

          <el-table-column
            prop="createTime"
            header-align="left"
            align="left"
            label="创建时间"
            width="300"
          >
          </el-table-column>
          <el-table-column
              header-align="center"
              align="center"
              label="操作">
            <template slot-scope="scope">
              <el-button v-if="permissions.service_mailtemplate_view&&scope.row.enableStatus===1" type="text" size="small" icon="el-icon-view"
                         @click="addOrUpdateHandle(scope.row.mailTemplateId,1)">查看
              </el-button>
              <el-button v-if="permissions.service_mailtemplate_edit&&scope.row.enableStatus==0" type="text" size="small" icon="el-icon-edit"
                         @click="addOrUpdateHandle(scope.row.mailTemplateId)">编辑
              </el-button>
              <el-button v-if="permissions.service_mailtemplate_del&&scope.row.enableStatus==0" type="text" size="small" icon="el-icon-delete"
                         @click="deleteHandle(scope.row.mailTemplateId,scope.row.name)">删除
              </el-button>




            </template>
          </el-table-column>
          <template v-slot:empty>
            <el-image
              src="https://cdn.hnjngl.hnrrcz.com/common/noData.png"
              style="margin-top: 70px; width: 255px"
              fit="fill"
            ></el-image>
            <div
              class="noData"
              style="
                  position: relative;
                  margin: -70px auto -5px;
                  font-size: 14px;
                  color: #999;
                "
            >
              你还没有邮件模板信息,请点击去新增
            </div>
            <el-button
              type="primary"
              size="medium"
              style="min-width: 129px; margin-bottom: 50px"
              @click="addOrUpdateHandle()"
            >去新增</el-button
            >
          </template>
        </el-table>
      </div>

      <div class="avue-crud__pagination">
        <el-pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle"
                       :current-page="searchForm.current" :page-sizes="[10,20,50,100]"
                       :page-size="searchForm.size" :total="totalPage" background
                       layout="total,sizes,prev,pager,next,jumper"></el-pagination>
      </div>
      <!-- 弹窗, 新增 / 修改 -->
      <table-form v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getDataList"></table-form>
    </div>



  </div>
</template>

<script>
import {fetchList,delObj,putObj,} from '@/api/service/mailTemplate'
import TableForm from './mailTemplate-form'
import Toolbar from "@/components/Toolbar"
import {mapGetters} from 'vuex'
import {getDicDataSource} from "@/util/common";
import {getStore} from "@/util/store";



export default {
  data() {
    return {
      searchForm: {
        current: 1,
        size: 10,
        enableStatus: '',
      },
      timeArray: [],
      dataList: [],
      pageIndex: 1,
      pageSize: 10,
      totalPage: 0,
      showSearch: true,
      dataListLoading: false,
      addOrUpdateVisible: false,
      load: false,
      userInfo: {},
    }
  },
  components: {
    TableForm,
    Toolbar
  },
  created() {
    this.userInfo = getStore({name: 'userInfo'});
    console.log("this.userInfo:",this.userInfo);
    this.getDataList()
  },
  computed: {
    ...mapGetters(['permissions'])
  },
  methods: {
    //时间搜索
    timeArrayChange(val) {
      if (val) {
        val[0] = val[0].substr(0, 10) + " 00:00:00";
        val[1] = val[1].substr(0, 10) + " 23:59:59";
      }
    },
    // 获取数据列表
    getDataList() {
      this.dataListLoading = true
      this.load = false;
      let data = {
        timeArray: this.timeArray,
        ...this.searchForm
      }
      fetchList(data).then(response => {
        this.dataList = response.data.data.records
        this.totalPage = response.data.data.total
        this.load = true;
      })
      this.dataListLoading = false
      console.log("list");
    },
    //每页数
    sizeChangeHandle(val) {
      this.searchForm.size = val;
      this.searchForm.current = 1;
      this.load = false;//重新加载
      this.getDataList();
    },
    //当前页
    currentChangeHandle(val) {
      console.log("page");
      this.searchForm.current = val;
      this.load = false;//重新加载
      this.getDataList();
    },
    // 新增 / 修改
    addOrUpdateHandle(id,views) {
      this.addOrUpdateVisible = true
      console.log(id, views);
      this.$nextTick(() => {
        this.$refs.addOrUpdate.init(id,views);
      })
    },
    // 删除
    deleteHandle(id, name) {
      let that = this
      this.$confirm('是否确认删除:' + name, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(function () {
        delObj(id).then(res => {
          if (res.data.data){
            that.$message.success('删除成功')
            that.getDataList()
          }else {
            that.$message.error('删除失败,当前文件有模板选用')
            that.getDataList()
          }
        })
      }).then(data => {

      })
    },
    handleQuery() {
      this.searchForm.current = 1;
      this.load = false;//重新加载
      this.getDataList();
    },
    resetQuery() {
      this.searchForm.enableStatus = "";
      this.timeArray = [];
      this.searchForm.name = '';

      this.$refs['searchForm'].resetFields();
      this.handleQuery();
    },
    // 消息通知开关

    switchChange(row) {
      this.$confirm(
        `是否确认${row.enableStatus == 1 ? " 关闭 " : " 打开 "}该邮件模板(${
          row.name
        })的启用功能`,
        "提示",
      ).then((res) => {
        this.dataListLoading = true;
        const result = row.enableStatus == 1 ? 0 : 1;
        putObj({
          mailTemplateId: row.mailTemplateId,
          enableStatus: result,
        })
          .then((res) => {

            this.dataListLoading = false;
            if (res.data.code === 0) {
              this.$message.success(`${result === 1 ? "打开" : "关闭"}成功`);
              // 根据接口调用成功修改switch状态
              row.enableStatus = result;
              this.getDataList();
            }
          })
          .catch(() => {
            this.dataListLoading = false;
            this.$message.error(`${result === 1 ? "打开" : "关闭"}失败`);
          });
      });

    },

  }
}
</script>
<style scoped lang="scss">
/deep/.cell {
  max-height: 110px;
  overflow-y: hidden;
}
/*查看截图水平居中*/
/*
/deep/.drag-inner {
  top: 50%!important;
  left: 50%;
  transform: translate(-50%,-50%);
}
*/

/deep/.el-icon-zoom-in {
  margin-right: 0!important;
}


.div-mask-one {
  position: absolute;
  bottom: 0px;
  left: 0px;
  width: 100px;
  cursor: pointer;
  height: 100px;
  background-color: rgba(0, 0, 0, 0.37);
  /* 垂直居中展示 注意点 如果使用绝对居中,其内容内容要用一个div包起来 */
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
  font-size: 16px;
  color: #ffffff;
  transition: height 300ms;
  top: 1px;
}

.mask-one-p {
  width: 30px;
  height: 30px;
  display: flex;
  justify-content: center;
  align-items: center;
}


/deep/.eval-switch.el-switch.is-disabled {
  opacity: 1;

  .el-switch__core {
    cursor: pointer;
  }
}
</style>

表单页

vue-quill-editor富文本编辑器_富文本编辑器_04


vue-quill-editor富文本编辑器_elementui_05

vue-quill-editor富文本编辑器_elementui_06

<template>
  <el-dialog
    :title="!dataForm.mailTemplateId ? '新增邮件模板' : views && dataForm.mailTemplateId ? '查看邮件模板' : '修改邮件模板'"
    :close-on-click-modal="false"
    :visible.sync="visible"
    v-if="visible"
  >
    <el-form
      :model="dataForm"
      :rules="dataRule"
      ref="dataForm"
      label-width="95px"
      label-position="left"
    >
      <el-form-item label="模板名称" prop="name">
        <cl-input v-model="dataForm.name" placeholder="请输入模板名称" :disabled="views"></cl-input>
      </el-form-item>

      <el-form-item label="模板内容" prop="content">
        <!--新增编辑-->
        <div v-if="!views">
          <quillEditors class="ql-editor" v-if="flag" :disabled="views" :content="dataForm.content"
                        @changeContent="changeContent"
          />
        </div>

        <!--查看-->
        <div v-html="dataForm.content" v-if="views && dataForm.mailTemplateId"></div>
      </el-form-item>

    </el-form>

    <span slot="footer" class="dialog-footer">
      <el-button @click="visible = false">取消</el-button>
      <el-button type="primary" @click="dataFormSubmit()" v-if="canSubmit"
        >确认{{ !dataForm.mailTemplateId ? '新增邮件模板' : '修改邮件模板'}}</el-button
      >
    </span>
  </el-dialog>
</template>

<script>
import { getObj, addObj, putObj } from "@/api/service/mailTemplate";

import { getDicDataSource } from "@/util/common";

export default {
  data() {
    return {
      visible: false,
      canSubmit: false,
      views: false,
      dataForm: {
        name: "",
        content: "",
      },
      dataRule: {
        name: [{ required: true, message: "模板名称不能为空", trigger: "blur" }],
        content: [{ required: true, message: "模板内容不能为空", trigger: "blur" }],
      },
      load:false,
      flag: false,//数据是否请求完毕
    };
  },
  created() {
  },
  components: { },
  methods: {
    init(id,views) {
      this.flag = false;
      console.log('views', id, views);
      if (views == 1) {
        this.views = true;
        this.canSubmit = false;
      } else {
        this.views = false;
        this.canSubmit = true;
      }
      this.dataForm.mailTemplateId = id || '';

      this.dataForm.content = "";
      this.dataForm.name = "";
      this.visible = true;
      this.$nextTick(() => {
        this.$refs['dataForm'].resetFields()

        if (this.dataForm.mailTemplateId) {
          getObj(this.dataForm.mailTemplateId).then((response) => {
            this.dataForm = response.data.data;
            this.flag = true;
          })
        } else {
          this.flag = true;
        }
      })
    },
    changeContent(val) {
      this.dataForm.content = val;
    },
    // 表单提交
    dataFormSubmit() {
      console.log(this.dataForm);

      this.$refs["dataForm"].validate((valid) => {
        if (valid) {
          this.canSubmit = false;
          if (this.dataForm.mailTemplateId) {
            putObj(this.dataForm)
              .then((data) => {
                this.$message({
                  message: "修改成功",
                  type: "success",
                });
                this.visible = false;
                this.$emit("refreshDataList");
              })
              .catch(() => {
                this.canSubmit = true;
              });
          } else {
            addObj(this.dataForm)
              .then((data) => {
                this.$message({
                  message: "添加成功",
                  type: "success",
                });
                this.visible = false;
                this.$emit("refreshDataList");
              })
              .catch(() => {
                this.canSubmit = true;
              });
          }
        }
      });
    },
  },
};
</script>
<style scoped lang="scss">
/deep/ #uploadContent {
  width: 440px;
}
</style>


标签:文本编辑,vue,false,val,views,data,dataForm,editor,true
From: https://blog.51cto.com/u_15694202/7850615

相关文章

  • vue项目中上传文件失败记录
    页面请求报【Failedtoloadresource:net::ERR_CONNECTION_ABORTED】错误,查了下是文件过大导致上传失败,element-ui本身没有大小限制,最后排查是Nginx默认是上传一个不能超过1M大小的文件#设置客户端传文件通过nginx大小client_max_body_size1024m;......
  • Vue3| create-vue 脚手架工具
    create-vue是Vue官方新的脚手架工具,底层切换到了vite(下一代构建工具),为开发提供极速响应 使用 create-vue创建项目:1.前提环境条件:  已安装16.0或更高版本的Node.js(node-v)2.创建一个Vue应用:npminitvue@latest(这一指令将会安装并执行create-vue)启动项目:......
  • 【前端开发】前端开发都应该知道的vueuse
    前言:我们在写项目业务时进场会要封装一些工具函数,经常会遇到重复造轮子现象,这里给大家普及下vueuse,是基于Vue组合式API的实用工具集。比如如下简单的几个例子:useDateFormat   时间格式处理函数useTimeAgo     几小时/上周前等处理函数 useMouse     ......
  • 【前端开发】vue3+vite项目部分优化
    1、使用rollup-plugin-visualizer可视化分析包npmirollup-plugin-visualizer-S在vite.config.js中引入 在plugins里面 然后执行npmrunbuild就自动打开可视化分析2、CDN加速在vite.config.js中引入import{autoComplete,PluginasimportToCDN}from"v......
  • vue实例挂载以及模板解析过程
    抽空看了下vue源码,记录下newVue()的过程。 在package.json中运行命令添加sourcemap,打包后在源码案例目录下创建新的html文件,运行后可以在控制台断点调试 测试代码<scriptsrc="../../dist/vue.js"></script><divid="demo"><p@click="searchQuery=333">{{sear......
  • 通过 modules 创建 vuex 的模块
    模块拆分:1.在store文件夹下再新建文件夹modules,在modules下新建xxx.js文件:eg:新建user.js文件conststate={ userInfo:{  name:'zs',  age:18 }, score:80}constmutations={}constactions={}constgetters={}exportdefault......
  • 使用vue在移动端显示树状多选功能
    最近的项目要求是做一个树状的多选功能,然而该项目是使用vant4作为前端的框架,vant4只有树状单选,没有多选的,那只能自己写一个了。借鉴博主https://blog.csdn.net/m0_68428581/article/details/130641982,我将他的代码转成了vue3的语法,并且根据自己的项目需求进了相关改动,终于实现......
  • 在vue中使用XLSX库实现Excel的导入导出
    XLSX库是个十分强大的利用前端js处理excel文档的库,官网:https://www.sheetjs.com/vue中安装即使用:安装pnpminstallxlsxpnpminstallxlsx-style-hzx//设置边框与格式用 使用<div@click="exportExcel"style="width:40px;height:40px;position:absolute;z-index......
  • Vue学习笔记(十):全局事件总线
      之前博客中介绍了prop和调用事件的方式在父-子组件之间进行数据,这种方式在只有一层嵌套层时可以使用,但是路过存在多层嵌套,多层多个“兄弟”组件之间传递数据,就非常麻烦。对此,vue中提供了一种全局事件总线机制,数据传递是通过一个空的Vue实例作为中央事件总线,通过它......
  • vue - alias
    3.别名alias配置:build\webpack.base.conf.js:module.exports={...,resolve:{extensions:['.js','.vue','.json'],alias:{'@':resolve('src'),'common':resolve('src......