1, the preface
WangEditor 5 has been in public beta for a while now, and in the public beta community there are often questions about the official vue component, so I’ve summarized some of the current flaws in @wangEditor /editor-for-vue@next from this perspective:
editorId
“Allows us to get an example of the editor, which is the end result, but not very efficient or silly to use. It needs to be used after the editor has been destroyededitorId
To manually clear the cache, which can cause a memory leak if the user forgets this step.- Setting content asynchronously requires additional variables to control the creation of the editor, adding complexity to use and not being silly enough
defaultContent
The data must be deeply cloned, and the operation is assigned to the user, which increases the complexity- Does not support
v-model
, push data synchronization to the user, increasing the complexity of use vue
Is a framework that supports bidirectional binding, and some of the particular configuration items in our component library are not responsive if the user can passeditable.config.readOnly = false
You can disable the editor and useeditable.mode = 'simple'
You can switch the editor mode, which saves the user n more lines of code and makes it even dumber to use- The handling of events can be used directly
config.onChange = () => {}
I don’t quite understand why I have to mention it alone - Special scenario: in a page, there is a list of articles on the left and an editor on the right. If you click an article in the list, the editor will automatically display the content of the article without any historical record (the needs of users in the QQ group before). In this case, the user can only continuously control a variable and assign a value to the variable
false
To assign a valuetrue
To destroy the rebuild editor if one is available to the userreloadEditor
The API will make it easier to use
On 21/12/21, I started trying to wrap a VUE3 component myself that I thought would work. It will be fully completed by 21/12/30.
This component supports the following functions:
- Support dynamic configuration of editor parameters (editor created after modification of the configuration items take effect)
- support
v-model
和v-model:html
Two forms of bidirectional binding - Support dynamic display of default content without a history of old documents
- The default configuration items are also supported
json array
,json string
和html string
Data in three formats - Natural support
TypeScript
For this reason, NPM package is not released at present. If necessary, you can get it from GitHub (only one file). If you think it is useful, you can give it to star.
2. Use of self-contained components
2.1. Global Registration components
import { createApp } from 'vue'
import wangeditor from 'xxx/wangeditor'
// Globally register the EditorToolbar, EditorEditable components
createApp(App).use(wangeditor).mount('#app')
Copy the code
2.2. Start fast
<style lang="scss">
.border {
border: 1px solid #ddd;
}
</style>
<template>
<editor-toolbar class="border" :option="toolbar" @reloadbefore="onToolbarReloadBefore" />
<editor-editable
class="border"
:option="editable"
v-model="formData.json"
v-model:html="formData.html"
@reloadbefore="onEditableReloadBefore"
/>
</template>
<script lang="ts">
import { Descendant } from 'slate'
import {
EditorEditable,
EditorEditableOption,
EditorToolbar,
EditorToolbarOption,
useWangEditor,
} from 'xxx/wangeditor'
import { defineComponent, shallowReactive } from 'vue'
export default defineComponent({
components: { EditorToolbar, EditorEditable },
setup() {
// Editor configuration
const editableOption: EditorEditableOption = {}
// Menu bar configuration
const toolbarOption: EditorToolbarOption = {}
// Buffeting duration. The editor is reloaded 365ms after the configuration item that triggers the reloading changes
const reloadDelary = 365
const { editable, toolbar, getEditable, getToolbar, clearContent, reloadEditor } = useWangEditor(
editableOption,
toolbarOption,
reloadDelary
)
// Enable read-only mode
editable.config.readOnly = true
/ / don't use reactive/ref, should use shallowReactive/shallowRef to receive the json data
const formData = shallowReactive({
json: [] as Descendant[],
html: ' ',})function onEditableReloadBefore(inst: IDomEditor) {
console.log('Editable about to reload:' + new Date().toLocaleString())
}
function onToolbarReloadBefore(inst: Toolbar) {
console.log(The 'Toolbar is about to reload:' + new Date().toLocaleString())
}
return { editable, toolbar, formData, onEditableReloadBefore, onToolbarReloadBefore }
},
})
</script>
Copy the code
2.3, Vue hook:useWangEditor
After useWangEditor processing, the returned Editable and Toolbar items correspond to the editor and menu bar configuration items, but the configuration item objects are responsive. We can update or reload the editor by directly modifying the editable/ Toolbar corresponding properties.
If editableOption and toolbarOption are passed in as reactive data, they are automatically disassociated internally, meaning that the editable and Toolbar configuration objects that are processed by useWangEditor, Changes in content will not trigger previous dependency updates!!
/** * vue hook, which implements dynamic binding of editor configuration items *@param {Object} Configuration of the body of the editableOption editor *@param {Object} ToolbarOption menu bar configuration *@param {Number} ReloadDelay Delay for controlling the load delay, in milliseconds */
declare function useWangEditor(
editableOption: EditorEditableOption | null = null,
toolbarOption: EditorToolbarOption | null = null,
reloadDelay: number = 365
) :{
editable: Required<EditorEditableOption>
toolbar: Required<EditorToolbarOption>
getEditable: () = > IDomEditor | undefined
getToolbar: () = > Toolbar | undefined
clearContent: () = > void
reloadEditor: () = > void
}
Copy the code
2.3.1 Configuration Items:EditorEditableOption
/** * editor configuration item */
interface EditorEditableOption {
/** Editor mode */mode? :'default' | 'simple'
/** The default for editor initialization */defaultContent? : Descendant[] |string | null
/** Editor configuration, the specific configuration is subject to the official */config? : Partial<IEditorConfig>/** V-model/V-model: HTML data synchronization chattering duration. Default value: 3650, in milliseconds */delay? :number
/** * The priority of the content when the editor is created. Default: true. * true: V-model > V-model: HTML > defaultContent. * false: defaultContent > V-model > V-model: HTML * /extendCache? :boolean
}
Copy the code
2.3.2 Configuration Items:EditorToolbarOption
/** * Menu bar configuration item */
interfaceEditorToolbarOption { mode? :'default' | 'simple'config? : Partial<IToolbarConfig> }Copy the code
2.4. Dynamically modify the configuration
const { editable, toolbar } = useWangEditor()
editable.config.placeholder = 'new placeholder'
// Switch to read-only mode
editable.config.readOnly = true
toolbar.mode = 'simple'
Copy the code
2.4.1 Data Priority:EditorEditableOption.extendCache
When v-model/v-model: HTML is used in conjunction with defaultContent, we can use extendCache configuration items to control the defaultContent of the overloaded editor.
When extendCahce is true, the priority of the content displayed when the editor is created/reloaded is v-Model > V-Model: HTML > defaultContent.
When extendCache is false, the priority of the content displayed during editor creation/reload is defaultContent > V-Model > V-model: HTML. False mode may cause data loss, so data must be saved before the editor reloads. We can configure the reloadbefore event to save data.
2.4.2 Default Values:EditorEditableOption.defaultContent
DefaultContent changes do not trigger editor reloading by default. If we want to display defaultContent directly, we need to use the reloadEditor to force the editor to reload. And we need to be aware of extendCache’s impact on the default content of the overloaded editor.
const { editable, toolbar, reloadEditor } = useWangEditor()
onMounted(() = > {
setTimeout(() = > {
// When you do v-model/ V-model: HTML binding, if you want to reset it after the editor is reloaded
// Set the default value of extendCache to false.
// This will result in the loss of editor content, which can be properly handled with the reloadbefore event
editable.extendCache = false
// Then modify the configuration
editable.defaultContent = [{ type: 'header1'.children: [{ text: 'Title one'}}]]String JSON is also supported
editable.defaultContent = '[{" type ":" header1 ", "children" : [{" text ", "a title"}]}]'
// It is compatible with HTML strings.
editable.defaultContent = ' Heading a
Paragraph
'
// Finally, you need to forcibly reload the editor
reloadEditor()
}, 5000)})Copy the code
2.5. Editor/menu bar reloading
EditorEditableOption mode, EditorEditableOption. Config. HoverbarKeys, EditorEditableOption. Config. MaxLength, EditorEditableO Changes to ption. Config. customPaste trigger reloading of the editor. The other EditorEditableOption options only support dynamic configuration but do not trigger reloading, which avoids unnecessary resource consumption. If you need to force an editor reload, the reloadEditor API is also provided for users to manually trigger.
Unlike EditorEditableOption, any change in EditorToolbarOption triggers a menu bar reload.
const { reloadEditor } = useWangEditor()
// Force the editor to reload
reloadEditor()
Copy the code
2.5.1 Before reloading:reloadbefore
The event
Before the editor is reloaded, the reloadBefore event is emitted.
<template>
<editor-toolbar :option="toolbar" @reloadbefore="onToolbarReloadBefore" />
<editor-editable v-model="formData.json" :option="editable" @reloadbefore="onEditableReloadBefore" />
</template>
<script lang="ts">
import axios from 'axiios'
import { Descendant } from 'slate'
import { EditorEditable, EditorToolbar, useWangEditor } from 'xxx/wangeditor'
import { defineComponent, shallowReactive } from 'vue'
export default defineComponent({
components: { EditorToolbar, EditorEditable },
setup() {
const { editable, toolbar, reloadEditor } = useWangEditor()
const formData = shallowReactive({
json: [] as Descendant[],
})
function onEditableReloadBefore(inst: IDomEditor) {
window.alert('Editable about to reload')
console.log('Editable about to reload:' + new Date().toLocaleString())
// Submit data
axios.post('xxx/xxx', formData)
}
function onToolbarReloadBefore(inst: Toolbar) {
window.alert('Toolbar about to reload')
console.log(The 'Toolbar is about to reload:' + new Date().toLocaleString())
}
return { editable, toolbar, formData, onEditableReloadBefore, onToolbarReloadBefore }
},
})
</script>
Copy the code
2.6. Clear the content
Not only will the editor content be cleared, but v-Model/V-Model: HTML data will also be synchronized
const { clearContent } = useWangEditor()
clearContent()
Copy the code
2.7. Get menu bar instance
const { getToolbar } = useWangEditor()
const toolbarInstance: Toolbar | undefined = getToolbar()
if (toolbarInstance) {
// do somthing
} else {
// do somthin
}
Copy the code
2.8. Get the editor instance
const { getEditable } = useWangEditor()
const editableInstance: IDomEditor | undefined = getEditable()
if (editableInstance) {
console.log(editableInstance.children)
} else {
console.error('Editor not instantiated')}Copy the code
2.9. Support for V-Model
EditorEditable supports v-Model and V-Model: HTML data binding, corresponding to JSON array and HTML String respectively. Both formats can be bound at the same time, or they can be bound separately to either V-Model or V-Model: HTML, or they can be bound without data binding.
V-model: HTML binding only is not recommended, there are inevitable defects!! And be aware of the possible impact of extendCache!!
At the same time, as we proceedv-model
This parameter is recommended for bindingshallowReactive
/shallowRef
To cachejson array
The data. If you insist on usingreactive
/ref
If you cache data, unknown errors occur at runtime, and you may not find the problem. Important! Important!!!!! Important!!
<template>
<editor-editable :option="editable" v-model="formData.json" v-model:html="formData.html" />
</template>
<script lang="ts">
import { Descendant } from 'slate'
import { useWangEditor } from '@we/wangeditor'
import { defineComponent, shallowReactive } from 'vue'
export default defineComponent({
setup() {
const { editable } = useWangEditor()
const formData = shallowReactive({
json: [] as Descendant[],
html: ' ',})return { editable, formData }
},
})
</script>
Copy the code
or
<template>
<editor-editable :option="editable" v-model="jsonData" v-model:html="htmlData" />
</template>
<script lang="ts">
import { Descendant } from 'slate'
import { useWangEditor } from '@we/wangeditor'
import { defineComponent, shallowRef } from 'vue'
export default defineComponent({
setup() {
const { editable } = useWangEditor()
const jsonData = shallowRef<Descendant[]>([])
const htmlData = ref(' ')
return { editable, jsonData, htmlData }
},
})
</script>
Copy the code
3, summarize
What impressed me most about this package was that it was a responsive API, and that bugs came from responsive apis. So, if you’re also using third-party libraries that use responsive data, Use toRaw, markRaw, shallowReactive, shallowReadonly, unref, and shallowRef apis to remove the responsiveness of data. Otherwise, runtime bugs are not so easy to fix.
The official wangEditor example for addressing runtime bugs caused by reactive features (Issues :262) is a deep clone of the data, which is not elegant, but is exceptionally useful and simple. Of course, in this component, as long as you follow the documentation, you don’t have to worry about it.
4, the last
For this reason, NPM package is not released at present. If necessary, you can get it from GitHub (only one file). If you think it is useful, you can give it to star.