preface

WangEditor is a compact, lightweight, rich text editor. However, when used in VUE, it is difficult for some students to package wangEditor as a component that supports bidirectional binding (V-Model)

First, understand the V-Model principle

First, let’s take a look at how the official documentation describes the custom V-Model:

If you still don’t understand, let’s do a comparative experiment:

V -bind:value=” HTML “+ V -on:input=”(e) => {this.html = e.targe. value}” It makes a lot more sense now.

Implement v-Model in components

I understand the principle of V-Model, but how to package it? The main points are as follows:

  • In custom components:
    • We need to startpropsTo define avalueTo accept the value passed in by the parent component
    • And then we need to use$emit('input', newValue)Send the new value to the parent component
  • In the parent component:
    • usev-modelBidirectional binding

/components/wang-editor.vue

Step 1: Initialize the use of wangEditor in the.vue file, following normal usage steps

<template>
    <div ref="wang"></div>
</template>

<script>
import wangEditor from 'wangeditor'

export default {
    data() {
        return {
            editor: null
        }
    },
    mounted() {
        this.editor = new wangEditor(this.$refs.wang)
        this.editor.create()
    },
    beforeDestroy() {
        if (this.editor) {
            this.editor.destroy()
        }
    }
}
</script>
Copy the code

Step 2: Define props. Value to accept values from the parent component

export default {
    props: {
    	value: {
            type: String.default: ' '}},mounted() {
        this.editor = new wangEditor(this.$refs.wang)
        this.editor.create()
        
        // If the parent component passes in a value, it assigns the value to the editor
        if (this.value.length) {
            this.editor.txt.html(this.value)
        }
    },
}
Copy the code

Step 3: use $emit(‘input’, newVal) to send the new value to the parent component

export default {
    mounted() {
        this.editor = new wangEditor(this.$refs.wang)

        // V-model bidirectional binding: sends the value to the parent component
        this.editor.txt.eventHooks.changeEvents.push(() = > {
            this.$emit('input'.this.editor.$textElem.html())
        })

        this.editor.create()
        
        // If the parent component passes in a value, it assigns the value to the editor
        if (this.value.length) {
            this.editor.txt.html(this.value)
        }
    },
}
Copy the code

Iii. Final code

Continue wrapping on top of the V-Model, and then take a look at the more complete code

/components/wang-editor.vue

<template> <div ref="wang"></div> </template> <script> import wangEditor from 'wangeditor' export default { props: {// wangEditor configuration option: {type: Object, default() {return {}}, // Accepts the value of the parent component // https://cn.vuejs.org/v2/guide/components-custom-events.html#%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BB%84%E4%BB%B6%E7%9A%84-v-mod El value: {type: String, default: "}}, watch: {// Listen for the parent component to pass the value to the editor value(n) {if (this.editor && n! == this.temp) {this.editor.$textelem.html (n)}}}, data() {return {temp: }}, mounted() {this.editor = new wangEditor(this.$refs.wang) // Add object.assign (this.editor. Config, This.option) // V-model two-way binding: The value to send to the parent component (do not take up the user's onchange configuration) enclosing editor. TXT. EventHooks. ChangeEvents. Push (() = > {this. Temp = this.editor.$textElem.html() this.$emit('input', this.temp) }) this.editor.create() if (this.value.length) { this.editor.txt.html(this.value) } }, beforeDestroy() { if (this.editor) { this.editor.destroy() } } } </script>Copy the code

4. Use wang-Editor component

<template> <div id="app"> <wang-editor :option="option" v-model="html"></wang-editor> </div> </template> <script> import  WangEditor from './components/wang-editor.vue' export default { name: 'App', components: { WangEditor }, data() { return { option: { height: 500 }, html: '<p>like</p>' } }, } </script>Copy the code