QuillEditor无法识别显示含有div和转义字符的问题

30 篇文章 0 订阅
4 篇文章 0 订阅

在解决前端根据爬取抓过来的数据时,要显示到富文本框中,如下:

<div class=\"info_cont\" id=\"zoomcon\">\n <p><br></p><p style=\";text-align: justify;font-family: Calibri;font-size: 14px;white-space: normal;text-indent: 43px\"><span style=\"font-family: 仿宋_GB2312;font-size: 21px\"><span style=\"font-family:仿宋_GB2312\">近日,工业和信息化部等部门联合印发《绿色建材产业高质量发展实施方案》(以下简称《方案》),明确了目标任务,到</span><span style=\"font-family:仿宋_GB2312\">2026年,绿色建材年营业收入超过3000亿元,总计培育30个以上特色产业集群,建设50项以上绿色建材应用示范工程 ,政府采购政策实施城市不少于100个,绿色建材产品认证证书达到12000张。到2030年,绿色建材全生命周期内“节能、减排、低碳、安全、便利和可循环”水平进一步提升,形成一批国际知名度高的绿色建材生产企业和产品品牌。江苏作为绿色建材大省、绿色建材下乡活动试点地区,有责任也有义务率先推动《方案》落地见效,发挥试点带动作用,全力打造绿色建材高质量发展的江苏样板。</span></span></p><p style=\";text-align: justify;font-family: Calibri;font-size: 14px;white-space: normal;text-indent: 43px\"><span style=\"font-family: 黑体;font-size: 21px\"><span style=\"font-family:黑体\">一、充分认识《方案》的出台对促进绿色建材企业高质量发展的重大意义。</span></span><span style=\"font-family: 仿宋_GB2312;font-size: 21px\"><span style=\"font-family:仿宋_GB2312\">推进绿色建材产业高质量发展,企业是重要的承载体。《方案》中提出了坚持系统观念,统筹扩大内需和深化供给侧结构性改革,促进建材工业绿色化转型,推动绿色建材增品种、提品质、创品牌,提升全产业链内生力、影响力、增长力、支撑力,加速绿色建材产业高质量发展的总体要求,为企业未来走什么样的路径,指明了方向、提供了遵循。其中不仅明确了集群培育、政府采购、绿色认证等近期目标,还明确了到</span><span style=\"font-family:仿宋_GB2312\">2030年“形成一批国际知名度高的绿色建材生产企业和产品品牌”的中期目标,使企业发展更精准地找到发力点。《方案》中明确了推进产业高质量发展的4个方面12项重点任务及国家有关部门的职责分工,形成了有利于绿色建材产业发展的良好政策环境,对企业发展形成强有力的支撑。</span></span></p><p style=\";text-align: justify;font-family: Calibri;font-size: 14px;white-space: normal;text-indent: 43px\"><span style=\"font-family: 黑体;font-size: 21px\"><span style=\"font-family:黑体\">二、着力推进建材企业绿色化、智能化、协同化发展。</span></span><span style=\"font-family: 仿宋_GB2312;font-size: 21px\"><span style=\"font-family:仿宋_GB2312\">一是要加快生产过程绿色化。强化工艺升级、能源替代、节能降耗、资源循环利用等综合性措施,实现污染物和碳排放双下降。要优化用能结构,推动清洁生产,争创环保绩效</span><span style=\"font-family:仿宋_GB2312\">A、B级或绩效引领性企业,培育10个以上行业节能降碳技术创新示范企业。要以“六零”工厂为目标,建设“一零”试点生产,尤其是水泥、玻璃、陶瓷、玻纤及制品等重点行业企业更要开展节能降碳技术集成应用,到2026年创建省级以上绿色工厂100家。二是要加速生产方式智能化。推进企业加快推进与新一代信息技术深度融合,促进智能化生产、规模化定制、服务化延伸。到2026年,省级以上智能车间和智能工厂超过50家,关键序数控化率超过70%。推进建材企业积极探索多品种、小批量绿色建材产品柔性生产方式,更好适应定制化差异化需求。三是要推进产业发展协同化。建材企业要发挥“城市环境净化器”作用,利用工业窑炉协同处置各项废弃物和垃圾。增强企业核心竞争力,积极争创单项冠军企业。</span></span></p><p style=\";text-align: justify;font-family: Calibri;font-size: 14px;white-space: normal;text-indent: 43px\"><span style=\"font-family: 黑体;font-size: 21px\"><span style=\"font-family:黑体\">三、着力推进企业增品种、提品质、创品牌。</span></span><span style=\"font-family: 仿宋_GB2312;font-size: 21px\"><span style=\"font-family:仿宋_GB2312\">“增品种、提品质、创品牌”是企业提升影响力的重要手段。要推进企业加快实施“三品”行动:一是要加快推动产品升级,如水泥、玻璃等生产企业要推动低碳化、制品化发展;装饰、装修材料企业要推进产品功能化、装配化发展。要加大新产品开发,特别是围绕城市更新改造需求和农房绿色低碳建设需求,发展配套的绿色建材产品,到2026年,绿色建材认证产品生产企业超过600家。二是要努力提升产品品质。积极建立满足绿色建材生产的全过程控制及质量管控体系,严格生产工艺,全面提升产品质量,向卓越质量攀升。三是要扩大品牌影响。引导和鼓励企业制定品牌发展战略,创新品牌传播模式,加大品牌建设投入,推出更多让利于民的优惠促销措施。支持企业积极参与品牌价值评价、品牌宣传周、“绿色建材下乡”等活动,大力培育商标品牌,支持优质企业参与“江苏精品”认证,争创中国质量奖、省长质量奖等奖项,主动参与国际合作,不断增强国际社会对企业品牌的认同。</span></span></p><p style=\";text-align: justify;font-family: Calibri;font-size: 14px;white-space: normal;text-indent: 43px\"><span style=\"font-family: 黑体;font-size: 21px\"><span style=\"font-family:黑体\">四、着力推进企业加大模式、技术、产品创新。</span></span><span style=\"font-family: 仿宋_GB2312;font-size: 21px\"><span style=\"font-family:仿宋_GB2312\">一是要创新消费模式。推动生产企业主动联合房地产、建筑设计、装饰装修企业提供菜单式、定制化应用方案,探索装饰装修一体化服务新模式。企业家居体验馆、生活馆等新零售模式向社区和农村下沉,满足消费者多样化、个性化需求。二是要加大科技创新。企业要加大科技创新投入,积极联合上下游企业、高校、科研院所等,构建产学研用相结合的创新体系,进行工艺设备和产品攻关。联合软件开发商、装备制造商开展国产化替代技术攻关,打造一批具有自主知识产权、具有行业特点的专业工业软件和智能装备,并推进适应性改造与规模化应用,打造</span><span style=\"font-family:仿宋_GB2312\">10个智能制造单项应用及系统集成应用典范项目。</span></span><span style=\"font-family: 仿宋_GB2312;font-size: 21px\"><span style=\"font-family:仿宋_GB2312\">(</span></span><span style=\"font-family: 仿宋_GB2312;font-size: 21px\"><span style=\"font-family:仿宋_GB2312\">江苏省工业和信息化厅</span></span><span style=\"font-family: 仿宋_GB2312;font-size: 21px\"><span style=\"font-family:仿宋_GB2312\">)</span></span></p><p><br></p>\n </div>

QuillEditor标签无法识别它,如下

解决方法:先创建html,把内容复制给这个html

 

/** 编辑 */

async function editService(data) {

  let res  = await getPolicyDetail(data.id);

  serviceForm.value = {...res};

  console.log("serviceForm.value",serviceForm.value.content);

  serviceForm.value.content=htmlDecode(serviceForm.value.content);

  provinceData();

  text.value = "编辑政策";

  disabled1.value = false;

  dialogVisibleService.value = true;

}

解决方式

function htmlDecode(input) {

  console.log("input",input.innerHTML);

  var e = document.createElement('div');

  e.innerHTML = input;

  console.log("e",e);

  console.log("e.childNodes",e.childNodes);

  console.log("e.innerHTML",e.innerHTML);

  if(e.childNodes.length>1){

    return e.innerHTML

  }

  else{

    return e.childNodes[0].innerHTML;

  }

  // return  e.childNodes[0].innerHTML;

  //return e.childNodes.length === 0 ? '' : e.childNodes[0].innerHTML;

}

具体代码

<el-col :span="24">
  <el-form-item label="政策解读" prop="content">
    <Editor :modelValue="serviceForm.content" :disabled="disabled1"/>
  </el-form-item>
</el-col>

import Editor from "@/components/Editor";

<script setup>
    /** 编辑 */
async function editService(data) {
  let res  = await getPolicyDetail(data.id);
  serviceForm.value = {...res};
  console.log("serviceForm.value",serviceForm.value.content);
  serviceForm.value.content=htmlDecode(serviceForm.value.content);
  provinceData();
  text.value = "编辑政策";
  disabled1.value = false;
  dialogVisibleService.value = true;
}

function htmlDecode(input) {
  console.log("input",input.innerHTML);
  var e = document.createElement('div');
  e.innerHTML = input;

  console.log("e",e);
  console.log("e.childNodes",e.childNodes);

  console.log("e.innerHTML",e.innerHTML);

  if(e.childNodes.length>1){
    return e.innerHTML
  }
  else{
    return e.childNodes[0].innerHTML;
  }

  //return e.innerHTML;

  // if(e.childNodes.length==1){
  //   return e.childNodes[0].innerHTML;
  // }
  // else if(e.childNodes.length > 1){
  //   const htmlStr="";
  //   for(var i=0;i<e.childNodes.length;i++)
  //   {
  //     console.log("htmlStr",e.childNodes[i]);
  //     htmlStr+=e.childNodes[i];
  //   }

  //   console.log("htmlStr",htmlStr);
  //   return htmlStr;
  // }

  // return  e.childNodes[0].innerHTML;
  //return e.childNodes.length === 0 ? '' : e.childNodes[0].innerHTML;
}
</script>

 /components/Editor/index.vue文件

<template>
  <div>
    <el-upload
      :action="uploadUrl"
      :before-upload="handleBeforeUpload"
      :on-success="handleUploadSuccess"
      :on-error="handleUploadError"
      class="editor-img-uploader"
      name="file"
      :show-file-list="false"
      :headers="headers"
      ref="uploadRef"
      v-if="type == 'url'"
    >
    </el-upload>
    <div class="editor">
      <quill-editor
        ref="quillEditorRef"
        v-model:content="content"
        contentType="html"
        @textChange="(e) => $emit('update:modelValue', content)"
        :options="options"
        :style="styles"
      />
    </div>
  </div>
</template>

<script setup>
import { QuillEditor, Quill } from '@vueup/vue-quill';
import '@vueup/vue-quill/dist/vue-quill.snow.css';
import { getToken } from "@/utils/auth";

const props = defineProps({
  /* 编辑器的内容 */
  modelValue: {
    type: String,
  },
  /* 高度 */
  height: {
    type: Number,
    default: null,
  },
  /* 最小高度 */
  minHeight: {
    type: Number,
    default: null,
  },
  /* 只读 */
  readOnly: {
    type: Boolean,
    default: false,
  },
  /* 上传文件大小限制(MB) */
  fileSize: {
    type: Number,
    default: 5,
  },
  /* 类型(base64格式、url格式) */
  type: {
    type: String,
    default: "url",
  }
});

const { proxy } = getCurrentInstance();
// 上传的图片服务器地址
const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/system/oss/upload");
const headers = ref({ Authorization: "Bearer " + getToken() });
const quillEditorRef = ref();

const options = ref({
  theme: "snow",
  bounds: document.body,
  debug: "warn",
  modules: {
    // 工具栏配置
    toolbar: {
      container: [
        ["bold", "italic", "underline", "strike"],       // 加粗 斜体 下划线 删除线
        ["blockquote", "code-block"],                    // 引用  代码块
        [{ list: "ordered" }, { list: "bullet"} ],       // 有序、无序列表
        [{ indent: "-1" }, { indent: "+1" }],            // 缩进
        [{ size: ["small", false, "large", "huge"] }],   // 字体大小
        [{ header: [1, 2, 3, 4, 5, 6, false] }],         // 标题
        [{ color: [] }, { background: [] }],             // 字体颜色、字体背景颜色
        [{ align: [] }],                                 // 对齐方式
        ["clean"],                                       // 清除文本格式
        ["link", "image", "video"]                       // 链接、图片、视频
      ],
      handlers: {
        image: function (value) {
          if (value) {
            // 调用element图片上传
            document.querySelector(".editor-img-uploader>.el-upload").click();
          } else {
            Quill.format("image", true);
          }
        },
      },
    }
  },
  placeholder: "请输入内容",
  readOnly: props.readOnly,
});

const styles = computed(() => {
  let style = {};
  if (props.minHeight) {
    style.minHeight = `${props.minHeight}px`;
  }
  if (props.height) {
    style.height = `${props.height}px`;
  }
  return style;
});

const content = ref("");
watch(() => props.modelValue, (v) => {
  if (v !== content.value) {
    content.value = v === undefined ? "<p></p>" : v;
  }
}, { immediate: true });

// 图片上传成功返回图片地址
function handleUploadSuccess(res, file) {
  // 如果上传成功
  if (res.code == 200) {
    // 获取富文本实例
    let quill = toRaw(quillEditorRef.value).getQuill();
    // 获取光标位置
    let length = quill.selection.savedRange.index;
    // 插入图片,res为服务器返回的图片链接地址
    quill.insertEmbed(length, "image", res.data.url);
    // 调整光标到最后
    quill.setSelection(length + 1);
    proxy.$modal.closeLoading();
  } else {
    proxy.$modal.loading(res.msg);
    proxy.$modal.closeLoading();
  }
}

// 图片上传前拦截
function handleBeforeUpload(file) {
  const type = ["image/jpeg", "image/jpg", "image/png", "image/svg"];
  const isJPG = type.includes(file.type);
  //检验文件格式
  if (!isJPG) {
    proxy.$modal.msgError(`图片格式错误!`);
    return false;
  }
  // 校检文件大小
  if (props.fileSize) {
    const isLt = file.size / 1024 / 1024 < props.fileSize;
    if (!isLt) {
      proxy.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
      return false;
    }
  }
  proxy.$modal.loading("正在上传文件,请稍候...");
  return true;
}

// 图片失败拦截
function handleUploadError(err) {
  proxy.$modal.msgError("上传文件失败");
}

</script>

<style>
.editor-img-uploader {
  display: none;
}
.editor, .ql-toolbar {
  white-space: pre-wrap !important;
  line-height: normal !important;
}
.quill-img {
  display: none;
}
.ql-snow .ql-tooltip[data-mode="link"]::before {
  content: "请输入链接地址:";
}
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
  border-right: 0px;
  content: "保存";
  padding-right: 0px;
}

.ql-snow .ql-tooltip[data-mode="video"]::before {
  content: "请输入视频地址:";
}

.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
  content: "14px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
  content: "10px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
  content: "18px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
  content: "32px";
}

.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
  content: "文本";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
  content: "标题1";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
  content: "标题2";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
  content: "标题3";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
  content: "标题4";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
  content: "标题5";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
  content: "标题6";
}

.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
  content: "标准字体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
  content: "衬线字体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
  content: "等宽字体";
}
</style>

  • 28
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吱吱喔喔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值