需求
需求是这样的,点击富文本的“插入链接”菜单,打开“Insert Link”弹出框,如下图:
问题描述
弹出框里内容较多,按组件化思想,我们肯定是做一个组件来实现弹框(InsertLinkModal.vue)。
我们的思路是:按照wangeditor官方文档,自定义一个按钮菜单,点击这个菜单,控制弹出框的显示与否。代码如下:
// index.vue 文件
<template>
<div>
<div id="reviewReplyEditor"></div>
<insert-link-modal :visible="insertLinkModalVisible" @update:visible="v => insertLinkModalVisible = v" @ok="insertLink" />
</div>
</template>
<script>
import E from 'wangeditor'
import i18next from 'i18next'
import InsertLinkModal from './InsertLinkModal.vue'
import CustomLink from '@/utils/editor-custom-menu-link'
export default {
name: 'ReviewReply',
components: { InsertLinkModal },
data () {
return {
replyCont: null,
editor: null,
insertLinkModalVisible: false
}
},
mounted () {
this.$nextTick(() => {
this.initEditor()
})
},
methods: {
initEditor () {
this.editor = new E('#reviewReplyEditor')
this.editor.menus.extend('myInsertLink', CustomLink)
this.editor.config.lang = 'en'
this.editor.i18next = i18next
this.editor.config.height = 150
this.editor.config.zIndex = 1
this.editor.config.menus = ['myInsertLink']
this.editor.config.showMenuTooltips = false
this.editor.config.placeholder = '请输入内容...'
this.editor.config.onchange = () => {
this.replyCont = this.editor.txt.html()
}
this.editor.create()
},
}
}
</script>
// editor-custom-menu-link.js 文件
import E from 'wangeditor'
const { $, BtnMenu } = E
export default class CustomLink extends BtnMenu {
constructor (editor) {
// data-title属性表示当鼠标悬停在该按钮上时提示该按钮的功能简述
const $elem = $(
`<div class="w-e-menu" data-title="链接"><em class="w-e-icon-link"></em></div>`
)
super($elem, editor)
}
// 菜单点击事件
clickHandler () {
// 做任何你想做的事情
// 可参考【常用 API】文档,来操作编辑器
alert('hello world')
}
}
现在问题来了,我们如何才能在菜单的点击响应事件中控制弹出框的显示呢?弹出框的显示是用this.insertLinkModalVisible
控制的,关键是怎么把这个this
传到clickHandler
里。这里的this
实际上就是index.vue
这个组件实例。
解决方案
v5版本的wangeditor和v4版本的解决方案不一样,下面我们分别来说一下。
V5版本
请看官方文档:
可以看到,V5版本注册菜单,先声明了一个配置对象,再把配置对象作为参数传给registerMenu
:
const menu1Conf = {
key: 'menu1', // 定义 menu key :要保证唯一、不重复(重要)
factory() {
return new YourMenuClass() // 把 `YourMenuClass` 替换为你菜单的 class
}
}
那我们就可以在new YourMenuClass()的时候把this
传进去呀,只要在YourMenuClass类里接收好this
,那我们就可以通过this
来控制弹出框的显示了有没有。思路就是这样,代码我就不上了吧~
参考文档:
www.wangeditor.com/v5/developm…
github.com/wangeditor-…
V4版本
因为v4版本的菜单注册是这样的:this.editor.menus.extend('myInsertLink', CustomLink)
,CustomLink
就是你定义的菜单class,就没有一个地方可以把this
传进去。
所以只能另辟蹊径了。直接上代码:
// index.vue 文件
<template>
<div>
<div id="reviewReplyEditor"></div>
</div>
</template>
<script>
import E from 'wangeditor'
import i18next from 'i18next'
import CustomLink from '@/utils/editor-custom-menu-link'
export default {
name: 'ReviewReply',
data () {
return {
replyCont: null,
editor: null
}
},
mounted () {
this.$nextTick(() => {
this.initEditor()
})
},
methods: {
initEditor () {
this.editor = new E('#reviewReplyEditor')
this.editor.menus.extend('myInsertLink', CustomLink)
this.editor.config.lang = 'en'
this.editor.i18next = i18next
this.editor.config.height = 150
this.editor.config.zIndex = 1
this.editor.config.menus = ['myInsertLink']
this.editor.config.showMenuTooltips = false
this.editor.config.placeholder = '请输入内容...'
this.editor.config.onchange = () => {
this.replyCont = this.editor.txt.html()
}
this.editor.create()
},
}
}
</script>
// editor-custom-menu-link.js 文件
import InsertLinkModal from '@/components/InsertLinkModal.vue'
import Vue from 'vue'
import E from 'wangeditor'
const { $, BtnMenu } = E
export default class CumstomLink extends BtnMenu {
constructor (editor) {
// data-title属性表示当鼠标悬停在该按钮上时提示该按钮的功能简述
const $elem = $(
`<div class="w-e-menu" data-title="链接"><em class="w-e-icon-link"></em></div>`
)
super($elem, editor)
// 初始化链接弹框
this.$ele = document.createElement('div')
document.body.appendChild(this.$ele)
this.$ele.id = 'CumstomMenuInsertLinkModal'
// new一个vue实例
this.$root = new Vue({
el: '#CumstomMenuInsertLinkModal',
render: h => h(InsertLinkModal, {
ref: 'linkModal',
on: {
ok: (text, url) => {
editor.cmd.do('insertHTML', `<a href="${url}">${text}</a>`)
}
}
})
})
}
// 菜单点击事件
clickHandler () {
this.$root.$refs.linkModal.open()
}
}
解决思路就是:把弹出框组件import到菜单类里,通过new一个vue实例来挂载弹出框组件,然后就可以通过vue实例来查找到弹出框组件实例,从而控制它的显示了。这里是通过弹出框组件内部实现的一个open方法,来控制显示的。
// InsertLinkModal.vue 文件
<template>
<a-modal v-model="modalVisible" title="Insert Link" width="60%" :footer="null" :destroyOnClose="true" class="insert-link-modal">
....
</a-modal>
</template>
<script>
export default {
name: 'InsertLinkModal',
data () {
return {
modalVisible: false
}
},
methods: {
open () {
this.modalVisible = true
}
}
}
</script>
参考文档:
www.wangeditor.com/v4/pages/11…
github.com/wangeditor-…