| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- <template>
- <!-- 组件外部的 form-item -->
- <div style="z-index: 100; border: 1px solid #ccc; width: 100%">
- <Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
- <Editor
- :style="{ height: props.height + 'px', overflowY: 'hidden' }"
- v-model="content"
- :defaultConfig="editorConfig"
- :mode="props.mode"
- @onCreated="handleCreated" />
- <a-modal style="z-index: 1000" v-model:visible="resourceVisible" :render-to-body="false" :width="1080" :footer="false" draggable>
- <template #title>资源选择器</template>
- <sa-resource v-model="list" multiple ref="resource" returnType="url" />
- </a-modal>
- </div>
- </template>
- <script setup>
- import '@wangeditor/editor/dist/css/style.css'
- import { onBeforeUnmount, ref, shallowRef, watch, computed } from 'vue'
- import { Boot } from '@wangeditor/editor'
- import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
- import { useAppStore } from '@/store'
- import commonApi from '@/api/common'
- import file2md5 from 'file2md5'
- import tool from '@/utils/tool'
- const resourceVisible = ref(false)
- const appStore = useAppStore()
- const props = defineProps({
- modelValue: { type: String },
- component: Object,
- height: { type: Number, default: 300 },
- mode: { type: String, default: 'default' },
- customField: { type: String, default: undefined },
- })
- const emit = defineEmits(['update:modelValue', 'change'])
- let registerWangEditorButtonFlag = appStore.appCurrentSetting.registerWangEditorButtonFlag
- const list = ref([])
- const resource = ref()
- let content = computed({
- get() {
- return props.modelValue
- },
- set(value) {
- emit('update:modelValue', value)
- },
- })
- watch(
- () => content.value,
- (vl) => emit('change', vl)
- )
- watch(
- () => list.value,
- (imgs) => {
- let tmp = ''
- imgs.map((img) => {
- if (
- img.indexOf('.jpg') > -1 ||
- img.indexOf('.png') > -1 ||
- img.indexOf('.bmp') > -1 ||
- img.indexOf('.jpeg') > -1 ||
- img.indexOf('.svg') > -1 ||
- img.indexOf('.gif') > -1
- ) {
- const node = { type: 'image', src: img, href: '', alt: '', style: {}, children: [{ text: '' }] }
- editorRef.value.insertNode(node)
- }
- })
- resource.value.clearSelecteds()
- resourceVisible.value = false
- }
- )
- const editorRef = shallowRef()
- const toolbarConfig = {}
- toolbarConfig.excludeKeys = ['group-video', 'insertImage']
- class MyButtonMenu {
- constructor() {
- this.title = '资源选择器'
- this.tag = 'button'
- }
- // 获取菜单执行时的 value ,用不到则返回空 字符串或 false
- getValue(editor) {
- return ''
- }
- // // 菜单是否需要激活(如选中加粗文本,“加粗”菜单会激活),用不到则返回 false
- isActive(editor) {
- return false
- }
- // 菜单是否需要禁用(如选中 H1 ,“引用”菜单被禁用),用不到则返回 false
- isDisabled(editor) {
- return false
- }
- // 点击菜单时触发的函数
- exec(editor, value) {
- editor.emit('click_menu')
- }
- }
- const menu1Conf = {
- key: 'menu1', // 定义 menu key :要保证唯一、不重复(重要)
- factory() {
- return new MyButtonMenu()
- },
- }
- if (registerWangEditorButtonFlag === undefined || registerWangEditorButtonFlag === false) {
- Boot.registerMenu(menu1Conf)
- appStore.setRegisterWangEditorButtonFlag(true)
- }
- toolbarConfig.insertKeys = {
- index: 1, // 插入的位置,基于当前的 toolbarKeys
- keys: ['menu1'],
- }
- const editorConfig = {
- placeholder: '请输入内容...',
- MENU_CONF: {},
- hoverbarKeys: {
- // 在编辑器中,选中链接文本时,要弹出的菜单
- link: {
- menuKeys: [
- // 默认的配置可以通过 `editor.getConfig().hoverbarKeys.image` 获取
- 'imageWidth30',
- 'imageWidth50',
- 'imageWidth100',
- '|', // 分割符
- 'imageFloatNone', // 增加 '图片浮动' 菜单
- 'imageFloatLeft',
- 'imageFloatRight',
- '|', // 分割符
- 'editImage',
- 'viewImageLink',
- 'deleteImage',
- ],
- },
- },
- }
- editorConfig.MENU_CONF['uploadImage'] = {
- async customUpload(file, insertFn) {
- uploadRequest(file, 'image', 'uploadImage').then((res) => {
- insertFn(tool.attachUrl(res.url))
- })
- },
- }
- const uploadRequest = async (file, type, method, requestData = {}) => {
- const hash = await file2md5(file)
- const dataForm = new FormData()
- dataForm.append(type, file)
- dataForm.append('isChunk', false)
- dataForm.append('hash', hash)
- for (let name in requestData) {
- dataForm.append(name, requestData[name])
- }
- const response = await commonApi[method](dataForm)
- return response.data
- }
- const handleCreated = (editor) => {
- editorRef.value = editor
- editorRef.value.on('click_menu', () => {
- resourceVisible.value = true
- })
- }
- onBeforeUnmount(() => {
- const editor = editorRef.value
- if (editor == null) return
- editor.destroy()
- })
- </script>
- <style scoped></style>
|