目标:在 wangEditor5 编辑器的基础上,封装成自己的编辑器组件,实现 v-model 指令。
npm i @wangeditor/editor @wangeditor/editor-for-vue -s
// MyEditor.vue 文件
<template>
<div style="border: 1px solid #ccc;">
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editor"
:defaultConfig="toolbarConfig"
:mode="mode"
/>
<Editor
style="height: 500px; overflow-y: hidden;"
v-model="html"
:defaultConfig="editorConfig"
:mode="mode"
@onCreated="onCreated"
/>
</div>
</template>
<script>
import Vue from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
export default Vue.extend({
components: { Editor, Toolbar },
data() {
return {
editor: null,
html: '<p>hello</p>',
toolbarConfig: { },
editorConfig: { placeholder: '请输入内容...' },
mode: 'default', // or 'simple'
}
},
methods: {
onCreated(editor) {
this.editor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错
},
},
beforeDestroy() {
const editor = this.editor
if (editor == null) return
editor.destroy() // 组件销毁时,及时销毁编辑器
}
})
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>
// 父组件
<template>
<div class="page">
<my-editor v-model="msg"></my-editor>
</div>
</template>
<script>
import MyEditor from '../components/Editor.vue'
export default {
data(){
return {
msg:'andy'
}
},
methods:{
},
components:{
MyEditor
}
}
</script>
以上完成了准备工作,但是 v-model 指令直接用在 自定义组件上是无法生效的,需要进一步处理。
1). 语法糖:指的是在计算机语言中添加的某种语法,这种语法对语言的编译结果和功能并没有实际影响, 但是却能更方便程序员使用该语言。使用语法糖能够减少代码量、增加程序的可读性,从而减少程序代码出错的机会。
2). v-model 是一种语法糖,会被解析为一个名为 value 的自定义属性 :value
和一个名为 input 的自定义事件 @input
// 以下两行代码功能相同,实现了数据的双向绑定
<input type="text" v-model="msg">
<input type="text" :value="msg" @input="">
my-editor 组件
可以通过父传子
的数据传输方式通过 props 接收 value
这个自定义属性// MyEditor.vue 文件
props:{
value:{
type:String
}
},
// MyEditor.vue 文件
// 父组件传过来的值通过 watch 进行监听,变化,就重新赋给编辑器
watch:{
value(val) {
const context = `<p>${val}</p>`
this.editor.setHtml(context);
// this.html = context; 和上一行代码实现效果一样
}
},
onChange() 函数监
听内容值的变化,发生变化,通过子传父
的数据传输方式,将最新值传递给父组件中的 msg// MyEditor.vue 文件
// onChange()函数: 当编辑器内容、选区变化时的回调函数
// 将变化的数据通过 editor.getText() 得到,通过 子传父 this.$emit 传给父组件
onChange(editor) {
const text = editor.getText();
this.$emit('input',text);
},
// MyEditor.vue 文件
// 方法1 在 created 生命周期中赋初值
created() {
// 赋初值
this.html = `<p>${this.value}</p>`;
},
// 方法2 在 onCreate 函数中赋初值
onCreated(editor) {
this.editor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错
// onCreated 编辑器创建完毕时的回调函数。赋 父组件给的初值
this.editor.setHtml(`<p>${this.value}</p>`);
},
在 wangEditor5 的基础上,添加 v-model 指令,封装为自定义组件。
其实在于对 v-model 的理解,v-model
可以看成 :value 和 @input
,子组件 my-editor 通过父传子 props 接收 value
, 子传父 this.$emit( ) 传递最新值到 父组件 @input
。v-model 语法糖简化了父组件代码的书写。
// 父组件
<template>
<div class="page">
<input type="text" v-model="msg">
<my-editor v-model="msg"></my-editor>
</div>
</template>
<script>
import MyEditor from '../components/Editor.vue'
export default {
data(){
return {
msg:'xindy'
}
},
methods:{
},
components:{
MyEditor
}
}
</script>
// MyEditor.vue 文件
<template>
<div style="border: 1px solid #ccc;">
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editor"
:defaultConfig="toolbarConfig"
:mode="mode"
/>
<Editor
style="height: 500px; overflow-y: hidden;"
v-model="html"
:defaultConfig="editorConfig"
:mode="mode"
@onCreated="onCreated"
@onChange="onChange"
/>
</div>
</template>
<script>
import Vue from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
export default Vue.extend({
components: { Editor, Toolbar },
data() {
return {
editor: null,
html: '',
toolbarConfig: { },
editorConfig: { placeholder: '请输入内容...' },
mode: 'default', // or 'simple'
}
},
props:{
value:{
type:String
}
},
methods: {
onCreated(editor) {
this.editor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错
// onCreated 编辑器创建完毕时的回调函数。赋 父组件给的初值
this.editor.setHtml(`<p>${this.value}</p>`);
},
// onChange 编辑器内容、选区变化时的回调函数 将变化的数据通过 editor.getText() 得到,通过 子传父 this.$emit 传给父组件
onChange(editor) {
const text = editor.getText();
this.$emit('input',text);
},
},
// 父组件传过来的值通过 watch 进行监听,变化,就重新赋给 编辑器
watch:{
value(val) {
const context = `<p>${val}</p>`
this.editor.setHtml(context);
// this.html = context;
}
},
created() {
// 赋初值
// this.html = `<p>${this.value}</p>`;
},
beforeDestroy() {
const editor = this.editor
if (editor == null) return
editor.destroy() // 组件销毁时,及时销毁编辑器
}
})
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>