wangEditor富文本编辑器在vue3中使用

WangEditor富文本编辑器使用

封装成组件

html 复制代码
<!-- wangEditor.vue -->
<template>
	<div class="BasicEditor" style="border: 1px solid #ccc">
		<Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig" mode="default" />
		<Editor style="height: 500px; overflow-y: hidden" v-model="showData" :defaultConfig="editorConfig" mode="default" @onCreated="handleCreated" />
	</div>
</template>
<script lang="ts">
import '@wangeditor/editor/dist/css/style.css'; // 引入 css
import {
	onBeforeUnmount,
	shallowRef,
	computed,
	defineComponent,
} from 'vue';
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import { IToolbarConfig } from '@wangeditor/editor';
import { IDomEditor } from '@wangeditor/editor';
export default defineComponent({
	props: ['show'],
	emits: {
		'update:show': (playload: any) => {
			if (playload) {
				return true;
			} else {
				return false;
			}
		},
	},
	components: {
		Editor,
		Toolbar,
	},
	setup(props, { emit }) {
		// 编辑器实例,必须用 shallowRef
		const editorRef = shallowRef();

		// 内容 HTML
		// const valueHtml = ref('<p>hello</p>')

		// 模拟 ajax 异步获取内容
		// onMounted(() => {
		// });
		const showData = computed({
			get: () => props.show,
			set: val => {
				emit('update:show', val);
			},
		});

		const toolbarConfig: Partial<IToolbarConfig> = {};
		toolbarConfig.toolbarKeys = [
			'redo',
			'undo',
			'clearStyle',
			'|',
			'headerSelect',
			// {
			// 	"key": "headerSelect",
			// 	"title": "正文",
			// 	"iconSvg": "",
			// 	"menuKeys": [
			// 		'header1', 'header2', 'header3', 'header4', 'header5'
			// 	]
			// },
			'fontSize',
			'fontFamily',
			'|',
			'bold',
			'italic',
			'underline',
			'sub',
			'sup',
			'through',
			'|',
			'color',
			'bgColor',
			'|',
			{
				key: 'group-justify',
				title: '对齐',
				iconSvg:
					'<svg viewBox="0 0 1024 1024"><path d="M768 793.6v102.4H51.2v-102.4h716.8z m204.8-230.4v102.4H51.2v-102.4h921.6z m-204.8-230.4v102.4H51.2v-102.4h716.8zM972.8 102.4v102.4H51.2V102.4h921.6z"></path></svg>',
				menuKeys: ['justifyLeft', 'justifyRight', 'justifyCenter', 'justifyJustify'],
			},
			{
				key: 'group-indent',
				title: '缩进',
				iconSvg: '<svg viewBox="0 0 1024 1024"><path d="M0 64h1024v128H0z m384 192h640v128H384z m0 192h640v128H384z m0 192h640v128H384zM0 832h1024v128H0z m0-128V320l256 192z"></path></svg>',
				menuKeys: ['indent', 'delIndent'],
			},
			'lineHeight',
			'|',
			'divider',
			'insertLink',
			'todo',
			'bulletedList',
			'numberedList',
			'insertTable',
			'blockquote',
		];
		const editorConfig = { placeholder: '请输入内容...' };
		// 组件销毁时,也及时销毁编辑器
		onBeforeUnmount(() => {
			const editor = editorRef.value;
			if (editor == null) return;
			editor.destroy();
		});
		const handleCreated = (editor: IDomEditor) => {
			editorRef.value = editor; // 记录 editor 实例,重要!
		};
		const insertSetHtml = (val: any) => {
			const editor = editorRef.value; // 获取 editor ,必须等待它渲染完之后
			if (editor == null) return;
			// 聚集后才可插入HTML 不聚焦无法插入
			editor.focus();
			editor.clear();
			editor.dangerouslyInsertHtml(val); // 执行 editor API
		};

		return {
			editorRef,
			//   valueHtml,
			mode: 'default', // 或 'simple'
			toolbarConfig,
			editorConfig,
			handleCreated,
			showData,
			insertSetHtml,
		};
	},
});
</script> 
<style lang='scss' scoped>
.BasicEditor {
	:deep()em.token.italic {
		font-style: italic !important;
	}
	:deep() .w-e-text-container *,
	:deep().w-e-toolbar * {
		word-break: break-all;
	}
	:deep() h5,
	.h5 {
		font-size: 14px;
	}

	:deep() h4,
	.h4 {
		font-size: 16px;
		font-weight: bold;
	}

	:deep() h3,
	.h3 {
		font-size: 18px;
		font-weight: bold;
	}

	:deep() h2,
	.h2 {
		font-size: 20px;
		font-weight: bold;
	}

	:deep() h1,
	.h1 {
		font-size: 22px;
		font-weight: bold;
	}
}
</style>

引入使用

html 复制代码
<template>
  <div>
    <BasicEditorForm ref="BasicEditorForm" v-model:show="messageContent" />
    <el-button type="primary" @click="getEditorInfo">获取编辑器里的内容</el-button>
  </div>
</template>
<script lang="ts">
import {
  defineComponent,
  reactive,
  toRefs,
} from "vue";
import BasicEditorForm from "./wangEditor.vue";
export default defineComponent({
  name: "pageEleven",
  components: {
    BasicEditorForm,
  },
  setup() {
    const state = reactive({
      messageContent: "<p></p>",
    });
    function getEditorInfo() {
      console.log(state.messageContent, "BasicEditorForm");
    }

    return {
      ...toRefs(state),
      getEditorInfo,
    };
  },
});
</script>
相关推荐
To_OC6 小时前
从一头雾水到跑通全流程:我用一个周末啃透了JWT登录鉴权
前端·后端·http
excel8 小时前
研究 Vue 3 源码的收获
前端·vue.js
可乐鸡翅yeah_10 小时前
业务中 M3U8 水印相关坑,硬水印和动态水印区别
前端·网络·数据库·ffmpeg·m3u8在线
lerhxx10 小时前
AI 应用如何高效优雅地恢复中断?—— "连接解耦 + 状态持久化"
前端·javascript
计算机魔术师10 小时前
METR 演示 AI 智能体如何篡改 Inspect 评估记录以掩盖不当行为
前端
前端snow11 小时前
ai agent --- 异步处理之 Rabbit MQ
前端
念何架构之路11 小时前
zap扩展生态与总结
java·前端·数据库
独孤九剑打醒他11 小时前
【原创开源】【概念设计】源 - 栅 - 漏 - 栅 - 源 横向双栅 MOS,低压交流多值逻辑芯片探索
前端·其他·架构·开源·硬件工程
mantou13211 小时前
我给 AI Agent 做了个「油猴」:让 Claude Code / Codex 直接用你已登录的浏览器
前端·javascript·后端
默_笙12 小时前
🍕 一个主编、三个工种、两本手册:搭一支 AI 调研队
前端·javascript