1. 目標
目標: wangEditor5 エディターに基づいて、それを独自のエディター コンポーネントにカプセル化し、v-model 命令を実現します。
2. 準備
- wangEditorをダウンロードしてインストールします
npm i @wangeditor/editor @wangeditor/editor-for-vue -s
- MyEditor.vue ファイルをコンポーネント コンポーネントに追加し、ファイルを初期化します。
// 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>
- 親コンポーネントに追加し、カスタムコンポーネント my-editor に v-model ディレクティブを追加します
// 父组件
<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 ディレクティブをカスタムコンポーネント上で直接使用することはできないため、さらに処理が必要です。
3. 知識のポイント
1). 構文シュガー: コンピューター言語に追加された特定の構文を指します。この構文は言語のコンパイル結果や機能に実際の影響を与えませんが、プログラマーが言語を使いやすくします。シンタックス シュガーを使用すると、コードの量が減り、プログラムの可読性が向上するため、プログラム コード エラーの可能性が減ります。
:value
2). v-model は、valueという名前のカスタム属性と input という名前のカスタム イベントに解析される糖衣構文です。@input
// 以下两行代码功能相同,实现了数据的双向绑定
<input type="text" v-model="msg">
<input type="text" :value="msg" @input="">
4. 事業の実現
- したがって、このカスタム属性を介し
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 に最新の値を渡します
(子コンポーネントは、this を通じてエディターの最新のコンテンツを渡すだけで済みます。$emit() )、親コンポーネントの v-model は @input カスタム イベントを自動的に受信します。追加の @input イベントを追加する必要はありません)
// 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>`);
},
5. まとめ
wangEditor5をベースにv-model命令を追加し、カスタムコンポーネントとしてパッケージ化します。
実際、それは v-model の理解にあり、my-editor を通過したサブコンポーネントとみなすv-model
ことができます。v-model 構文の Sugar は、親コンポーネント コードの記述を簡素化します。:value 和 @input
父传子 props 接收 value
子传父 this.$emit( ) 传递最新值到 父组件 @input
6. コードを完全に実装する
// 父组件
<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>