Files

178 lines
3.8 KiB
Vue
Raw Normal View History

2022-12-16 17:26:54 +08:00
<template>
<div
:style="`border: 1px solid #ccc; width: ${width}px`"
:class="{
disabled: readOnly,
}"
>
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editorRef"
:defaultConfig="toolbarConfig"
:mode="mode"
/>
<Editor
:style="`min-height: ${minHeight}px; height: ${height}px;
overflow-y: hidden`"
v-model="valueHtml"
:defaultConfig="editorConfig"
:mode="mode"
@onCreated="handleCreated"
@onChange="handleChange"
@onBlur="emitBlur"
/>
</div>
</template>
<script>
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
import { getToken } from "@/utils/auth";
import {
onBeforeUnmount,
ref,
shallowRef,
onMounted,
toRefs,
nextTick,
watch,
computed,
} from "vue";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
const baseUrl = import.meta.env.VITE_APP_BASE_API;
export default {
components: { Editor, Toolbar },
props: {
readOnly: {
type: Boolean,
default: false,
},
modelValue: {
type: String,
default: "",
},
placeholder: {
type: String,
default: "请输入内容",
},
minHeight: {
type: [String, Number],
default: 300,
},
height: {
type: [String, Number],
default: 300,
},
width: {
type: [String, Number],
default: 820,
},
mode: {
type: String,
default: "default", // or 'simple'
},
},
setup(props, context) {
// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef();
// editorRef.value.on("blur", () => {
// console.log("blur");
// });
// 内容 HTML
const valueHtml = ref("");
watch(
() => props.modelValue,
(val) => {
valueHtml.value = val;
},
{ immediate: true }
);
const { height } = toRefs(props);
const toolbarConfig = {
excludeKeys: [],
};
// onBlur: (editor) => {
// console.log("onBlur");
// },
const editorConfig = {
placeholder: props.placeholder,
readOnly: props.readOnly,
MENU_CONF: {
uploadImage: {
server: `${baseUrl}/common/upload`,
// 自定义增加 http header
fieldName: "file",
headers: {
Authorization: `Bearer ${getToken()}`,
},
customInsert(res, insertFn) {
// res 即服务端的返回结果
// console.log(res);
// 从 res 中找到 url alt href ,然后插图图片
insertFn(res.url, null, null);
},
},
},
};
const isEmpty = () => {
return editorRef.value.isEmpty();
};
// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {
const editor = editorRef.value;
if (editor == null) return;
editor.destroy();
});
const handleCreated = (editor) => {
editorRef.value = editor; // 记录 editor 实例,重要!
};
const handleChange = (editor) => {
if (editor.isEmpty()) {
context.emit("update:modelValue", "");
} else {
context.emit("update:modelValue", editor.getHtml());
}
};
context.expose({ isEmpty });
const emitBlur = () => {
context.emit("blur", editorRef.value);
// editorRef.value.emit("blur");
};
return {
editorRef,
valueHtml,
mode: "default", // 或 'simple'
toolbarConfig,
editorConfig,
height,
handleCreated,
handleChange,
// isEmpty,
emitBlur,
};
},
};
</script>
<style lang="scss" scoped>
.disabled {
background-color: #f5f7fa;
cursor: not-allowed;
:deep(.w-e-text-container) {
background-color: inherit;
// color: green;
opacity: 0.5;
}
:deep(.w-e-toolbar) {
user-select: none;
pointer-events: none;
background-color: inherit;
}
}
</style>