You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
389 lines
11 KiB
389 lines
11 KiB
<!--
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-06-25 08:57:59
|
|
@ 备注: QuillEditor 富文本编辑器
|
|
-->
|
|
<template>
|
|
<div :style="'display: block; width: 100%; height: '+height+'; padding-bottom: 25px; border: 1px solid #Eeeeee;'">
|
|
<QuillEditor
|
|
ref="quillRef"
|
|
v-model:content="content"
|
|
:options="myOptions"
|
|
contentType="html"
|
|
@update:content="setValue()"
|
|
/>
|
|
</div>
|
|
</template>
|
|
<script setup>
|
|
import Compressor from 'compressorjs';
|
|
import { QuillEditor, Quill } from '@vueup/vue-quill';
|
|
import '@vueup/vue-quill/dist/vue-quill.snow.css';
|
|
import ImageUploader from 'quill-image-uploader';
|
|
import ImageResize from 'quill-image-resize-custom-module';
|
|
import { uploadFilesSysFile } from '@/api/api';
|
|
import '@/styles/QuillFont.css'; // 字体和字体大小的自定义文件
|
|
|
|
|
|
|
|
// 设置行高的配置======start
|
|
const lineHeight = ['1', '1.25', '1.5', '1.75', '2.5', '3', '5'];
|
|
const parchment = Quill.import('parchment');
|
|
const lineHeightConfig = {
|
|
scope: parchment.Scope.INLINE,
|
|
whitelist: lineHeight,
|
|
};
|
|
const lineHeightStyle = new parchment.Attributor.Style(
|
|
'lineHeight',
|
|
'line-height',
|
|
lineHeightConfig,
|
|
);
|
|
Quill.register({ 'formats/lineHeight': lineHeightStyle }, true);
|
|
// 设置行高的配置======end
|
|
|
|
const props = defineProps({
|
|
// 左侧菜单数据
|
|
modelValue: String,
|
|
height:{
|
|
type:String,
|
|
default:"500px"
|
|
},
|
|
});
|
|
const emit = defineEmits(['update:modelValue']);
|
|
const content = ref('');
|
|
const quillRef = ref(null);
|
|
// 设置字体大小
|
|
const fontSizeStyle = Quill.import('attributors/style/size'); // 引入这个后会把样式写在style上
|
|
fontSizeStyle.whitelist = [
|
|
'12px',
|
|
'14px',
|
|
'16px',
|
|
'18px',
|
|
'20px',
|
|
'22px',
|
|
'24px',
|
|
'28px',
|
|
'30px',
|
|
'32px',
|
|
'34px',
|
|
'36px',
|
|
'38px',
|
|
'40px',
|
|
'42px',
|
|
'44px',
|
|
'46px',
|
|
'48px',
|
|
'50px',
|
|
'52px',
|
|
'54px',
|
|
'56px',
|
|
'60px',
|
|
];
|
|
// 设置字体
|
|
const fontStyle = Quill.import('attributors/style/font'); // 引入这个后会把样式写在style上
|
|
fontStyle.whitelist = [
|
|
'SimSun', // 宋体
|
|
'SimHei', // 黑体
|
|
'STFANGSO', // 华文仿宋
|
|
'Microsoft-YaHei', // 微软雅黑
|
|
'KaiTi', // 楷体
|
|
'FangSong', // 仿宋
|
|
'STKAITI', // 华文楷体
|
|
'Arial',
|
|
'Times-New-Roman',
|
|
'sans-serif',
|
|
];
|
|
|
|
Quill.register(fontSizeStyle, true);
|
|
Quill.register(fontStyle, true);
|
|
Quill.register('modules/imageUploader', ImageUploader);
|
|
Quill.register('modules/imageResize', ImageResize);
|
|
|
|
// 图片压缩
|
|
const compressImage = (file) => {
|
|
return new Promise((resolve, reject) => {
|
|
// eslint-disable-next-line no-new
|
|
new Compressor(file, {
|
|
quality: 0.6, // 设置压缩质量
|
|
success(result) {
|
|
resolve(result);
|
|
},
|
|
error(error) {
|
|
reject(error);
|
|
},
|
|
});
|
|
});
|
|
};
|
|
// 富文本配置项,将模块功能一起写入到配置项内,也可以单独配置Modules
|
|
const myOptions = reactive({
|
|
modules: {
|
|
toolbar: {
|
|
container: [
|
|
['bold', 'italic', 'underline', 'strike'], // 加粗、斜体、下划线、删除线
|
|
[{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题,不同级别的标题
|
|
[{ align: [] }], // 对齐方式
|
|
['blockquote', 'code-block'], // 引用,代码块
|
|
[{ script: 'sub' }, { script: 'super' }], // 上标/下标
|
|
[{ list: 'ordered' }, { list: 'bullet' }], // 有序、无序列表
|
|
[{ indent: '-1' }, { indent: '+1' }], // 缩进
|
|
['link', 'image', 'video'], // 超链接 图片 视频
|
|
[{ direction: 'rtl' }], // 文本方向
|
|
[{ color: [] }, { background: [] }], // 字体颜色和背景色
|
|
[{ size: fontSizeStyle.whitelist }], // 字体大小
|
|
[{ font: fontStyle.whitelist }], // 字体
|
|
[{ lineheight: lineHeight }], // 设置行高
|
|
['clean'], // 清除格式
|
|
],
|
|
handlers: {
|
|
lineheight: (value) => {
|
|
const editor = quillRef.value.getQuill();
|
|
if (value) {
|
|
editor.format('lineHeight', value);
|
|
}
|
|
},
|
|
},
|
|
},
|
|
|
|
// 设置图片的大小--可拖拽设置大小
|
|
imageResize: {
|
|
parchment: Quill.import('parchment'),
|
|
},
|
|
},
|
|
placeholder: '请输入内容...',
|
|
});
|
|
|
|
const setValue = () => {
|
|
// 用于设置双向绑定值
|
|
const text = toRaw(quillRef.value).getHTML();
|
|
emit('update:modelValue', text);
|
|
};
|
|
|
|
watch(
|
|
() => props.modelValue,
|
|
(val) => {
|
|
if (val) {
|
|
content.value = val; // 用于监听绑定值进行数据回填
|
|
} else {
|
|
// eslint-disable-next-line no-unused-expressions
|
|
toRaw(quillRef.value) && toRaw(quillRef.value).setContents(''); // 可用于弹窗使用富文本框关闭弹窗清除值
|
|
}
|
|
},
|
|
{
|
|
immediate: true, // 组件创建时立即执行一次回调
|
|
},
|
|
);
|
|
</script>
|
|
<style>
|
|
.ql-container {
|
|
height: calc(100% - 42px);
|
|
}
|
|
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value='SimHei']::before,
|
|
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='SimHei']::before {
|
|
font-family: SimHei;
|
|
content: '黑体';
|
|
}
|
|
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value='Microsoft-YaHei']::before,
|
|
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='Microsoft-YaHei']::before {
|
|
font-family: 'Microsoft YaHei';
|
|
content: '微软雅黑';
|
|
}
|
|
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value='KaiTi']::before,
|
|
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='KaiTi']::before {
|
|
font-family: KaiTi;
|
|
content: '楷体';
|
|
}
|
|
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value='FangSong']::before,
|
|
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='FangSong']::before {
|
|
font-family: FangSong;
|
|
content: '仿宋';
|
|
}
|
|
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value='SimSun']::before,
|
|
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='SimSun']::before {
|
|
font-family: SimSun;
|
|
content: '宋体';
|
|
}
|
|
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value='STFANGSO']::before,
|
|
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='STFANGSO']::before {
|
|
font-family: STFANGSO;
|
|
content: '华文仿宋';
|
|
}
|
|
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value='STKAITI']::before,
|
|
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='STKAITI']::before {
|
|
font-family: STKAITI;
|
|
content: '华文楷体';
|
|
}
|
|
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value='Arial']::before,
|
|
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='Arial']::before {
|
|
font-family: Arial;
|
|
content: 'Arial';
|
|
}
|
|
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value='Times-New-Roman']::before,
|
|
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='Times-New-Roman']::before {
|
|
font-family: 'Times New Roman';
|
|
content: 'Times New Roman';
|
|
}
|
|
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value='sans-serif']::before,
|
|
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='sans-serif']::before {
|
|
font-family: sans-serif;
|
|
content: 'sans-serif';
|
|
}
|
|
.ql-font-SimSun {
|
|
font-family: SimSun;
|
|
}
|
|
.ql-font-SimHei {
|
|
font-family: SimHei;
|
|
}
|
|
.ql-font-Microsoft-YaHei {
|
|
font-family: 'Microsoft YaHei';
|
|
}
|
|
.ql-font-KaiTi {
|
|
font-family: KaiTi;
|
|
}
|
|
.ql-font-FangSong {
|
|
font-family: FangSong;
|
|
}
|
|
.ql-font-Arial {
|
|
font-family: Arial;
|
|
}
|
|
.ql-font-Times-New-Roman {
|
|
font-family: 'Times New Roman';
|
|
}
|
|
.ql-font-sans-serif {
|
|
font-family: sans-serif;
|
|
}
|
|
|
|
/* 字号设置 */
|
|
|
|
/* 默认字号 */
|
|
.ql-snow .ql-picker.ql-size .ql-picker-label::before,
|
|
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
|
|
content: '字号';
|
|
}
|
|
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='12px']::before,
|
|
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='12px']::before {
|
|
font-size: 12px;
|
|
content: '12px';
|
|
}
|
|
.ql-size-12px {
|
|
font-size: 12px;
|
|
}
|
|
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='14px']::before,
|
|
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='14px']::before {
|
|
font-size: 14px;
|
|
content: '14px';
|
|
}
|
|
.ql-size-14px {
|
|
font-size: 14px;
|
|
}
|
|
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='16px']::before,
|
|
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='16px']::before {
|
|
font-size: 16px;
|
|
content: '16px';
|
|
}
|
|
.ql-size-16px {
|
|
font-size: 16px;
|
|
}
|
|
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='18px']::before,
|
|
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='18px']::before {
|
|
font-size: 18px;
|
|
content: '18px';
|
|
}
|
|
.ql-size-18px {
|
|
font-size: 18px;
|
|
}
|
|
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='20px']::before,
|
|
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='20px']::before {
|
|
font-size: 20px;
|
|
content: '20px';
|
|
}
|
|
.ql-size-20px {
|
|
font-size: 20px;
|
|
}
|
|
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='22px']::before,
|
|
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='22px']::before {
|
|
font-size: 22px;
|
|
content: '22px';
|
|
}
|
|
.ql-size-24px {
|
|
font-size: 24px;
|
|
}
|
|
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='24px']::before,
|
|
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='24px']::before {
|
|
font-size: 24px;
|
|
content: '24px';
|
|
}
|
|
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='26px']::before,
|
|
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='26px']::before {
|
|
font-size: 26px;
|
|
content: '26px';
|
|
}
|
|
.ql-size-26px {
|
|
font-size: 26px;
|
|
}
|
|
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='28px']::before,
|
|
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='28px']::before {
|
|
font-size: 28px;
|
|
content: '28px';
|
|
}
|
|
.ql-size-28px {
|
|
font-size: 28px;
|
|
}
|
|
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='30px']::before,
|
|
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='30px']::before {
|
|
font-size: 30px;
|
|
content: '30px';
|
|
}
|
|
.ql-size-30px {
|
|
font-size: 30px;
|
|
}
|
|
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='32px']::before,
|
|
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='32px']::before {
|
|
font-size: 32px;
|
|
content: '32px';
|
|
}
|
|
.ql-size-32px {
|
|
font-size: 32px;
|
|
}
|
|
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='36px']::before,
|
|
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='36px']::before {
|
|
font-size: 36px;
|
|
content: '36px';
|
|
}
|
|
.ql-size-36px {
|
|
font-size: 36px;
|
|
}
|
|
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='40px']::before,
|
|
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='40px']::before {
|
|
font-size: 40px;
|
|
content: '40px';
|
|
}
|
|
.ql-size-40px {
|
|
font-size: 40px;
|
|
}
|
|
.ql-snow .ql-picker.ql-lineheight .ql-picker-label::before {
|
|
content: '行高';
|
|
}
|
|
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='1']::before {
|
|
content: '1';
|
|
}
|
|
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='1.5']::before {
|
|
content: '1.5';
|
|
}
|
|
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='1.75']::before {
|
|
content: '1.75';
|
|
}
|
|
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='2']::before {
|
|
content: '2';
|
|
}
|
|
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='3']::before {
|
|
content: '3';
|
|
}
|
|
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='4']::before {
|
|
content: '4';
|
|
}
|
|
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='5']::before {
|
|
content: '5';
|
|
}
|
|
.ql-snow .ql-picker.ql-lineheight {
|
|
width: 70px;
|
|
}
|
|
</style>
|
|
|