修改自定义图片大小
效果
流程
注意
设置弹出弹出框 写好点击事件
绑定到菜单
修改 editorConfig 加入自定义宽高
代码
注意
必须使用
@ts-ignore
忽略掉细节重点看 ImageSize
MyMenu 就是插入图片
vue
<template>
<div style="border: 1px solid #ccc">
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editorRef"
:defaultConfig="toolbarConfig"
:mode="mode"
/>
<Editor
style="height: 500px; overflow-y: hidden"
v-model="valueHtml"
:defaultConfig="editorConfig"
:mode="mode"
@onCreated="handleCreated"
/>
<el-button type="primary" @click="getcontent">获取内容</el-button>
</div>
</template>
<script setup lang="ts">
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
import { onBeforeUnmount, ref, shallowRef, onMounted, watch } from "vue";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { SlateTransforms, SlateElement } from "@wangeditor/editor";
// 1. 引入boot
import { Boot } from "@wangeditor/editor";
// 设置内容
const props = defineProps({
html: {
type: String,
default: "",
},
});
watch(
() => {
return props.html;
},
() => {
valueHtml.value = props.html;
}
);
// 编辑器实例,必须用shallowRef包裹
const editorRef = shallowRef();
// 内容HTML
const valueHtml = ref("");
// 编辑器模式
const mode = ref("default"); // simple或者default;
// 模拟ajax异步获取数据内容
onMounted(() => {});
// 编辑器配置
const editorConfig = {
placeholder: "请输入内容...",
hoverbarKeys: {
image: {
menuKeys: [
"imageWidth30",
"imageWidth50",
"imageWidth100",
"imageSize",
"editImage",
"viewImageLink",
"deleteImage",
],
},
},
};
// 组件销毁的时候,也即时 销毁编辑器
onBeforeUnmount(() => {
const editor = editorRef.value;
if (editor == null) return;
editor.destroy();
});
// 编辑器示例
const handleCreated = (editor) => {
editorRef.value = editor; // 记录editor实例
};
// 获取到编辑器内容
const getcontent = () => {
console.log(valueHtml.value);
};
// 自定义节点
class MyMenu {
public title = "";
public tag = "";
public iconSvg = "";
constructor() {
// 自定义菜单标题
this.title = "自定义按钮";
// 类型
this.tag = "button";
// 自定义菜单图标
this.iconSvg =
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" t="1687315735883" class="icon" viewBox="0 0 1024 1024" version="1.1" p-id="13367" width="16" height="16" style="color:white;"><path stroke="#ff0000" fill="#ff0000" d="M890.88 63.488q28.672 0 52.736 10.752t41.984 29.184 28.16 43.52 10.24 53.76l0 620.544q0 28.672-10.24 53.76t-28.16 43.52-41.984 29.184-52.736 10.752l-689.152 0q-28.672 0-53.76-10.752t-43.52-29.184-29.184-43.52-10.752-53.76l0-620.544q0-28.672 10.752-53.76t29.184-43.52 43.52-29.184 53.76-10.752l689.152 0zM256 254.976q9.216 0 27.648 0.512t43.008 0.512l52.224 0 55.296 0q64.512 0 141.312-1.024l0-63.488-126.976 0 0-64.512-64.512 0 0 64.512-128 0 0 63.488zM377.856 360.448q-8.192-15.36-15.36-29.696-6.144-12.288-12.288-25.088t-9.216-20.992l-58.368 21.504 32.768 76.8zM254.976 756.736l101.376-143.36-66.56-26.624-98.304 145.408zM448.512 574.464l126.976 0 0-62.464-45.056 0-81.92 0 0-64.512q23.552 0 46.08 0.512t40.96 0.512l40.96 0 0-63.488-66.56 0q-19.456 0-40.96-1.024l68.608-65.536-68.608-32.768-20.48 98.304-257.024 0 0 63.488 35.84 0 47.104 0 53.248 0 56.32 0 0 64.512-128 0 0 62.464 40.96 0q18.432 0 40.96 0.512t46.08-0.512l0 129.024q0 16.384-2.048 27.136t-10.24 15.36-25.088 4.608-47.616-5.12q25.6 31.744 27.648 71.68 13.312-2.048 34.304-1.024t40.448-1.536 33.28-12.8 13.824-34.816l0-192.512zM568.32 685.056q-16.384-19.456-29.696-37.888-11.264-15.36-23.552-30.208t-18.432-23.04l-46.08 30.72 64.512 98.304zM896 379.904q-20.48-1.024-53.248-0.512t-63.488 1.536q-36.864 1.024-75.776 3.072l0-129.024q49.152 0 85.504-4.608t59.904-9.728q27.648-6.144 46.08-14.336-18.432-27.648-29.696-46.08-5.12-8.192-9.728-15.36t-7.68-11.264-3.584-4.608 1.536 4.608q-21.504 16.384-57.344 24.064t-69.632 10.752-57.344 3.072-21.504 0q1.024 16.384 1.536 44.032t0 77.824-1.024 129.024-0.512 196.608q0 13.312-3.072 33.28t-10.24 39.936-19.968 35.328-31.232 19.456q12.288 3.072 21.504 11.776t16.896 18.432 13.824 19.456 12.288 14.848q12.288-18.432 23.552-42.496t20.48-50.176 14.336-52.224 5.12-47.616l0-40.96 0-43.008 0-47.104 0-60.416 64.512 0 0 384 63.488 0 0-384q23.552 1.024 35.328 0.512t29.184 3.584l0-71.68z" p-id="13368"></path></svg>';
}
// 获取菜单执行时的value,用不到则返回空,字符串或者false
getValue(editor) {
console.log(editor);
return "自定义按钮";
}
// 菜单是否需要激活(如选中加粗文本,"加粗"菜单会激活) 用不到则返回 false
isActive(editor) {
return false; // or true
}
// 菜单是否需要禁用(如选中 H1 ,“引用”菜单被禁用),用不到则返回 false
isDisabled(editor) {
return false; // or true
}
// 点击菜单出发的函数
exec(editor, value) {
// 插入文本
// editor.insertText(value); // value 即 this.getValue(editor) 的返回值
// 插入对话框
// modalflag.value = true;
// 插入节点
const resulttext =
'<p><img src="https://dianyuan-public.oss-cn-shenzhen.aliyuncs.com/static/live/color_avatar/2.png"></p>';
editor.dangerouslyInsertHtml(resulttext);
}
}
const myMenuConf = {
key: "myMenu",
factory() {
return new MyMenu();
},
};
// 自定义节点
class imageSize {
public title = "";
public tag = "";
public iconSvg = "";
constructor() {
// 自定义菜单标题
this.title = "自定义按钮";
// 类型
this.tag = "button";
// 自定义菜单图标
this.iconSvg =
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" t="1687315735883" class="icon" viewBox="0 0 1024 1024" version="1.1" p-id="13367" width="16" height="16" style="color:white;"><path stroke="#ff0000" fill="#ff0000" d="M890.88 63.488q28.672 0 52.736 10.752t41.984 29.184 28.16 43.52 10.24 53.76l0 620.544q0 28.672-10.24 53.76t-28.16 43.52-41.984 29.184-52.736 10.752l-689.152 0q-28.672 0-53.76-10.752t-43.52-29.184-29.184-43.52-10.752-53.76l0-620.544q0-28.672 10.752-53.76t29.184-43.52 43.52-29.184 53.76-10.752l689.152 0zM256 254.976q9.216 0 27.648 0.512t43.008 0.512l52.224 0 55.296 0q64.512 0 141.312-1.024l0-63.488-126.976 0 0-64.512-64.512 0 0 64.512-128 0 0 63.488zM377.856 360.448q-8.192-15.36-15.36-29.696-6.144-12.288-12.288-25.088t-9.216-20.992l-58.368 21.504 32.768 76.8zM254.976 756.736l101.376-143.36-66.56-26.624-98.304 145.408zM448.512 574.464l126.976 0 0-62.464-45.056 0-81.92 0 0-64.512q23.552 0 46.08 0.512t40.96 0.512l40.96 0 0-63.488-66.56 0q-19.456 0-40.96-1.024l68.608-65.536-68.608-32.768-20.48 98.304-257.024 0 0 63.488 35.84 0 47.104 0 53.248 0 56.32 0 0 64.512-128 0 0 62.464 40.96 0q18.432 0 40.96 0.512t46.08-0.512l0 129.024q0 16.384-2.048 27.136t-10.24 15.36-25.088 4.608-47.616-5.12q25.6 31.744 27.648 71.68 13.312-2.048 34.304-1.024t40.448-1.536 33.28-12.8 13.824-34.816l0-192.512zM568.32 685.056q-16.384-19.456-29.696-37.888-11.264-15.36-23.552-30.208t-18.432-23.04l-46.08 30.72 64.512 98.304zM896 379.904q-20.48-1.024-53.248-0.512t-63.488 1.536q-36.864 1.024-75.776 3.072l0-129.024q49.152 0 85.504-4.608t59.904-9.728q27.648-6.144 46.08-14.336-18.432-27.648-29.696-46.08-5.12-8.192-9.728-15.36t-7.68-11.264-3.584-4.608 1.536 4.608q-21.504 16.384-57.344 24.064t-69.632 10.752-57.344 3.072-21.504 0q1.024 16.384 1.536 44.032t0 77.824-1.024 129.024-0.512 196.608q0 13.312-3.072 33.28t-10.24 39.936-19.968 35.328-31.232 19.456q12.288 3.072 21.504 11.776t16.896 18.432 13.824 19.456 12.288 14.848q12.288-18.432 23.552-42.496t20.48-50.176 14.336-52.224 5.12-47.616l0-40.96 0-43.008 0-47.104 0-60.416 64.512 0 0 384 63.488 0 0-384q23.552 1.024 35.328 0.512t29.184 3.584l0-71.68z" p-id="13368"></path></svg>';
// @ts-ignore
this.showModal = true; // 没有他就不会有弹出层
// @ts-ignore
this.modalWidth = 400;
// @ts-ignore
this.modalHeight = 500;
}
// 获取菜单执行时的value,用不到则返回空,字符串或者false
getValue(editor) {
console.log(editor);
return "自定义按钮";
}
// 菜单是否需要激活(如选中加粗文本,"加粗"菜单会激活) 用不到则返回 false
isActive(editor) {
return false; // or true
}
// 菜单是否需要禁用(如选中 H1 ,“引用”菜单被禁用),用不到则返回 false
isDisabled(editor) {
return false; // or true
}
// 点击菜单出发的函数
exec(editor, value) {}
getModalPositionNode(editor) {
return null; // modal 依据选区定位
}
// 定义 modal 内部的 DOM Element
getModalContentElem(editor) {
const content = document.createElement("div");
content.innerHTML = `
<form>
<div style="display: flex;align-items: center;">
宽度:<input id="width" placeholder="宽度" style="width: 180px;height: 30px;text-indent: 10px;" /> px
</div>
<div style="display: flex;align-items: center;margin-top:20px;">
高度:<input id="height" placeholder="高度" style="width: 180px;height: 30px;text-indent: 10px;" /> px
</div>
</form>
`;
const button = document.createElement("span");
button.style.padding = "5px 10px";
button.style.border = "1px solid #ccc";
button.style.borderRadius = "5px";
button.style.cursor = "pointer";
button.style.marginTop = "20px";
button.style.marginBottom = "20px";
button.style.backgroundColor = "#409eff";
button.style.color = "#fff";
button.style.display = "inline-block";
button.innerHTML = "确定";
content.appendChild(button);
button.onclick = () => {
// @ts-ignore
const width = content.querySelector("#width").value;
// @ts-ignore
const height = content.querySelector("#height").value;
// 选中图片父节点
editor.restoreSelection();
// 设置宽高
SlateTransforms.setNodes(
editor,
{
// @ts-ignore
style: {
width: `${width}px`,
height: `${height}px`,
},
},
{
// 添加match否则样式添加到图片父节点上
match: (node) => {
// @ts-ignore
if (SlateElement.isElement(node)) {
// @ts-ignore
if (node.type === "image") {
return true; // 匹配 image
}
}
return false;
},
}
);
};
return content;
}
}
const imageSizeConfig = {
key: "imageSize",
factory() {
return new imageSize();
},
};
// 工具栏配置
const toolbarConfig = {
insertKeys:
// {
// index: 0, // 插入的位置,基于当前的 toolbarKeys 如果多个就是
// keys: ['myMenu','imageSize']
// },
{
index: 0, // 插入的位置,基于当前的 toolbarKeys
keys: ["myMenu"],
},
};
// 这里必须要判断一下 避免重复注册
if (Boot.plugins.length < 13) {
Boot.registerMenu(myMenuConf);
Boot.registerMenu(imageSizeConfig);
}
defineExpose({
getcontent,
});
</script>
<style scoped lang="scss"></style>