|
阅读:60回复:0
@wangEditor 增加html代码编辑 功能
若依、芋道 vue3 & wangEditor @wangEditor 增加html代码编辑 功能:
在 components -- Editor -- src -- 更改editor.vue <template> <div class="border-1 border-solid border-[var(--tags-view-border-color)] z-10"> <div class="flex items-center justify-between border-0 b-b-1 border-solid border-[var(--tags-view-border-color)]" > <!-- 工具栏 --> <Toolbar v-show="!sourceMode" :editor="editorRef" :editorId="editorId" class="border-0 b-b-1 border-solid border-[var(--tags-view-border-color)]" /> <button type="button" class="px-3 py-1 text-sm border border-gray-300 rounded hover:bg-gray-50" @click="toggleSourceMode" > pw_ sourceMode ? '退出源码' : '源码编辑' </button> </div> <div v-show="sourceMode" class="p-3 bg-white"> <textarea v-model="sourceHtml" :style="sourceTextareaStyle" class="w-full border rounded p-2 font-mono" ></textarea> </div> <!-- 编辑器 --> <Editor v-show="!sourceMode" v-model="valueHtml" :defaultConfig="editorConfig" :editorId="editorId" :style="editorStyle" @on-change="handleChange" @on-created="handleCreated" /> </div> </template> <script lang="ts" setup> import { PropType } from 'vue' import { Editor, Toolbar } from '@wangeditor/editor-for-vue' import { i18nChangeLanguage, IDomEditor, IEditorConfig } from '@wangeditor/editor' import { propTypes } from '@/utils/propTypes' import { isNumber } from '@/utils/is' import { ElMessage } from 'element-plus' import { useLocaleStore } from '@/store/modules/locale' import { getRefreshToken, getTenantId } from '@/utils/auth' import { getUploadUrl } from '@/components/UploadFile/src/useUpload' import { min } from 'lodash-es' defineOptions({ name: 'Editor' }) type InsertFnType = (url: string, alt: string, href: string) => void const localeStore = useLocaleStore() const currentLocale = computed(() => localeStore.getCurrentLocale) const sourceMode = ref(false) const sourceHtml = ref('') i18nChangeLanguage(unref(currentLocale).lang) const props = defineProps({ editorId: propTypes.string.def('wangeEditor-1'), height: propTypes.oneOfType([Number, String]).def('500px'), editorConfig: { type: Object as PropType<Partial<IEditorConfig>>, default: () => undefined }, readonly: propTypes.bool.def(false), modelValue: propTypes.string.def('') }) const emit = defineEmits(['change', 'update:modelValue']) // 编辑器实例,必须用 shallowRef const editorRef = shallowRef<IDomEditor>() const valueHtml = ref('') watch( () => props.modelValue, (val: string) => { if (val === unref(valueHtml)) return valueHtml.value = val }, { immediate: true } ) // 监听 watch( () => valueHtml.value, (val: string) => { emit('update:modelValue', val) } ) const handleCreated = (editor: IDomEditor) => { editorRef.value = editor } // 编辑器配置 const editorConfig = computed((): IEditorConfig => { return Object.assign( { placeholder: '请输入内容...', readOnly: props.readonly, customAlert: (s: string, t: string) => { switch (t) { case 'success': ElMessage.success(s) break case 'info': ElMessage.info(s) break case 'warning': ElMessage.warning(s) break case 'error': ElMessage.error(s) break default: ElMessage.info(s) break } }, autoFocus: false, scroll: true, MENU_CONF: { ['uploadImage']: { server: getUploadUrl(), // 单个文件的最大体积限制,默认为 2M maxFileSize: 5 * 1024 * 1024, // 最多可上传几个文件,默认为 100 maxNumberOfFiles: 10, // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 [] allowedFileTypes: ['image/*'], // 自定义增加 http header headers: { Accept: '*', Authorization: 'Bearer ' + getRefreshToken(), // 使用 getRefreshToken() 方法,而不使用 getAccessToken() 方法的原因:Editor 无法方便的刷新访问令牌 'tenant-id': getTenantId() }, // 超时时间,默认为 10 秒 timeout: 15 * 1000, // 15 秒 // form-data fieldName,后端接口参数名称,默认值wangeditor-uploaded-image fieldName: 'file', // 上传之前触发 onBeforeUpload(file: File) { // console.log(file) return file }, // 上传进度的回调函数 onProgress(progress: number) { // progress 是 0-100 的数字 console.log('progress', progress) }, onSuccess(file: File, res: any) { console.log('onSuccess', file, res) }, onFailed(file: File, res: any) { alert(res.message) console.log('onFailed', file, res) }, onError(file: File, err: any, res: any) { alert(err.message) console.error('onError', file, err, res) }, // 自定义插入图片 customInsert(res: any, insertFn: InsertFnType) { insertFn(res.data, 'image', res.data) } }, ['uploadVideo']: { server: getUploadUrl(), // 单个文件的最大体积限制,默认为 10M maxFileSize: 10 * 1024 * 1024, // 最多可上传几个文件,默认为 100 maxNumberOfFiles: 10, // 选择文件时的类型限制,默认为 ['video/*'] 。如不想限制,则设置为 [] allowedFileTypes: ['video/*'], // 自定义增加 http header headers: { Accept: '*', Authorization: 'Bearer ' + getRefreshToken(), // 使用 getRefreshToken() 方法,而不使用 getAccessToken() 方法的原因:Editor 无法方便的刷新访问令牌 'tenant-id': getTenantId() }, // 超时时间,默认为 30 秒 timeout: 15 * 1000, // 15 秒 // form-data fieldName,后端接口参数名称,默认值wangeditor-uploaded-image fieldName: 'file', // 上传之前触发 onBeforeUpload(file: File) { // console.log(file) return file }, // 上传进度的回调函数 onProgress(progress: number) { // progress 是 0-100 的数字 console.log('progress', progress) }, onSuccess(file: File, res: any) { console.log('onSuccess', file, res) }, onFailed(file: File, res: any) { alert(res.message) console.log('onFailed', file, res) }, onError(file: File, err: any, res: any) { alert(err.message) console.error('onError', file, err, res) }, // 自定义插入图片 customInsert(res: any, insertFn: InsertFnType) { insertFn(res.data, 'mp4', res.data) } } }, uploadImgShowBase64: true, codeSelectLang: { HTML: 'HTML', CSS: 'CSS', JavaScript: 'JavaScript', TypeScript: 'TypeScript', JSON: 'JSON', XML: 'XML', SQL: 'SQL', Java: 'Java', Python: 'Python' } }, props.editorConfig || {} ) }) const sourceTextareaStyle = computed(() => ({ width: '80%', minWidth: `1150px`, minHeight: '200px', fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Courier New", monospace' })) const editorStyle = computed(() => { return { height: isNumber(props.height) ? `${props.height}px` : props.height } }) const toggleSourceMode = async () => { if (!sourceMode.value) { sourceHtml.value = unref(editorRef)?.getHtml() ?? valueHtml.value sourceMode.value = true return } sourceMode.value = false valueHtml.value = sourceHtml.value await nextTick() const editor = unref(editorRef) if (editor) { editor.setHtml(sourceHtml.value) editor.focus() } } // 回调函数 const handleChange = (editor: IDomEditor) => { emit('change', editor) } // 组件销毁时,及时销毁编辑器 onBeforeUnmount(() => { const editor = unref(editorRef.value) // 销毁,并移除 editor editor?.destroy() }) const getEditorRef = async (): Promise<IDomEditor> => { await nextTick() return unref(editorRef.value) as IDomEditor } defineExpose({ getEditorRef }) </script> <style src="@wangeditor/editor/dist/css/style.css"></style> <style lang="scss"> .w-e-text-placeholder { top: 7px !important; } </style> |
|