在vue3中我们可以使用@wangeditor/editor、@wangeditor/editor-for-vue来实现其功能
npm地址:https://www.npmjs.com/package/@wangeditor/editor-for-vue/v/5.1.12?activeTab=readme
官网:Editor
1. 安装
pnpm add @wangeditor/editor
# 或者 npm install @wangeditor/editor --save
pnpm add @wangeditor/editor-for-vue@next
# 或者 npm install @wangeditor/editor-for-vue@next --save
2. 组件封装
@/comps/Editor/index.vue
首先为了能让vue认识@wangeditor/editor-for-vue库、我们可以在.d.ts中声明一下即可
// 声明外部 npm 插件模块
declare module '@wangeditor/editor-for-vue';
<template>
<div class="Wft-Editor flex flex-col">
<Toolbar
class="default-border"
:editor="editorRef"
:mode="mode"
/>
<Editor
class="flex-1 overflow-y-auto"
v-model="valueHtml"
:defaultConfig="editorConfig"
:mode="mode"
@onCreated="handleCreated"
@onChange="onChange"
/>
</div>
</template>
<script setup lang="ts">
import '@wangeditor/editor/dist/css/style.css'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import type { IDomEditor } from '@wangeditor/editor'
import { onBeforeUnmount, shallowRef, computed, watch } from 'vue'
type TProps = {
mode?: string,
valueHtml?: string,
placeholder?: string,
disable?: boolean
}
const props = withDefaults(defineProps<TProps>(), {
mode: 'default', // or 'simple'
valueHtml: '',
placeholder: '请输入内容...',
disable: false
})
type TEmits = {
(e: 'update:valueHtml', params: string): void
(e: 'update:valueText', params: string): void
(e: 'onChange', params: IDomEditor): void
}
const emits = defineEmits<TEmits>()
const editorRef = shallowRef()
const valueHtml = computed({
get() {
return props.valueHtml
},
set(valueHtml) {
emits('update:valueHtml', valueHtml)
}
})
watch(() => props.disable, bool => {
if(!editorRef.value) return
bool ? (editorRef.value as IDomEditor).disable() : (editorRef.value as IDomEditor).enable()
}, { deep: true })
const editorConfig = computed(() => {
return { placeholder: props.placeholder }
})
// 记录 editor 实例,重要!
const handleCreated = (editor: IDomEditor) => {
editorRef.value = editor
}
// editor 改变
const onChange = (editor: IDomEditor) => {
emits('onChange', editor)
}
// 销毁编辑器
onBeforeUnmount(() => {
if(!editorRef.value) return
editorRef.value.destroy()
})
function getHtml() {
return (editorRef.value as IDomEditor).getHtml()
}
function getText() {
return (editorRef.value as IDomEditor).getText()
}
defineExpose({ getHtml, getText })
</script>
<style scoped>
.Wft-Editor {
width: 100%;
height: 100%;
}
.flex {
display: flex;
}
.flex-col {
flex-direction: column;
}
.default-border {
border-bottom: 1px solid #ccc;
}
.flex-1 {
flex: 1;
}
.overflow-y-auto {
overflow-x: hidden;
overflow-y: auto;
}
</style>
3. 使用
<template>
<div class="wel">
<div class="btn">
<button @click="submit">提交</button>
<button @click="getHtml">获取HTML</button>
<button @click="getText">获取TEXT</button>
<button @click="editorDisable = !editorDisable">{{ editorDisable ? '启用' : '禁用' }}</button>
</div>
<div class="editor-container">
<Editor
ref="EditorRef"
:disable="editorDisable"
v-model:value-html="editorValue"
@on-change="editorChange"
/>
</div>
</div>
</template>
<script setup lang="ts">
import Editor from '@/comps/Editor/index.vue'
import { onMounted, ref, shallowRef } from 'vue'
import type { IDomEditor } from '@wangeditor/editor'
let editorValue = ref('') // 提交的数据
let editorDisable = ref(false)
let EditorRef = shallowRef<InstanceType<typeof Editor>>()
onMounted(() => {
setTimeout(() => {
editorValue.value = '<h1>回显测试</h1>'
}, 3000)
})
const submit = () => {
console.log(editorValue.value)
}
const getHtml = () => {
console.log(EditorRef.value?.getHtml())
}
const getText = () => {
console.log(EditorRef.value?.getText())
}
const editorChange = (editor: IDomEditor) => {
console.log(editor.getHtml())
console.log(editor.getText())
}
</script>
<style scoped>
.wel {
width: 100%;
height: 100%;
}
.btn {
width: 100%;
height: 40px;
display: flex;
align-items: center;
}
.btn button {
margin-left: 15px;
}
.editor-container {
width: 100%;
height: calc(100% - 40px);
}
</style>
4. 效果