在解决前端根据爬取抓过来的数据时,要显示到富文本框中,如下:
<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>