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>
相关推荐
啃火龙果的兔子3 分钟前
前端单元测试覆盖率工具有哪些,分别有什么优缺点
前端·单元测试
「、皓子~30 分钟前
后台管理系统的诞生 - 利用AI 1天完成整个后台管理系统的微服务后端+前端
前端·人工智能·微服务·小程序·go·ai编程·ai写作
就改了33 分钟前
Ajax——在OA系统提升性能的局部刷新
前端·javascript·ajax
凌冰_35 分钟前
Ajax 入门
前端·javascript·ajax
京东零售技术1 小时前
京东小程序JS API仓颉改造实践
前端
奋飛1 小时前
TypeScript系列:第六篇 - 编写高质量的TS类型
javascript·typescript·ts·declare·.d.ts
老A技术联盟1 小时前
从小白入门,基于Cursor开发一个前端小程序之Cursor 编程实践与案例分析
前端·小程序
风铃喵游1 小时前
构建引擎: 打造小程序编译器
前端·小程序·架构
sunbyte1 小时前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | ThemeClock(主题时钟)
前端·javascript·css·vue.js·前端框架·tailwindcss
小飞悟1 小时前
🎯 什么是模块化?CommonJS 和 ES6 Modules 到底有什么区别?小白也能看懂
前端·javascript·设计