feat: 优化图片尺寸用于移动端

This commit is contained in:
sudoooooo 2024-07-18 21:07:25 +08:00
parent 492e0055f0
commit 2ed5b64b18
9 changed files with 131 additions and 84 deletions

1
web/components.d.ts vendored
View File

@ -17,7 +17,6 @@ declare module 'vue' {
ElDialog: typeof import('element-plus/es')['ElDialog']
ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElInput: typeof import('element-plus/es')['ElInput']
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
ElMenu: typeof import('element-plus/es')['ElMenu']

View File

@ -1,20 +1,38 @@
<template>
<div class="editor-wrapper border">
<Toolbar :class="['toolbar', props.staticToolBar ? 'static-toolbar' : 'dynamic-toolbar']" ref="toolbar"
v-show="showToolbar" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
<Editor class="editor" ref="editor" :modelValue="curValue" :defaultConfig="editorConfig" @onCreated="onCreated"
@onChange="onChange" @onBlur="onBlur" @onFocus="onFocus" :mode="mode" />
<Toolbar
:class="['toolbar', props.staticToolBar ? 'static-toolbar' : 'dynamic-toolbar']"
ref="toolbar"
v-show="showToolbar"
:editor="editorRef"
:defaultConfig="toolbarConfig"
:mode="mode"
/>
<Editor
class="editor"
ref="editor"
:modelValue="curValue"
:defaultConfig="editorConfig"
@onCreated="onCreated"
@onChange="onChange"
@onBlur="onBlur"
@onFocus="onFocus"
:mode="mode"
/>
</div>
</template>
<script setup>
import '@wangeditor/editor/dist/css/style.css'
import './styles/reset-wangeditor.scss'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { ref, shallowRef, onBeforeMount, watch, computed } from 'vue'
import { useStore } from 'vuex'
import { get as _get } from 'lodash-es'
import '@wangeditor/editor/dist/css/style.css'
import './styles/reset-wangeditor.scss'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { replacePxWithRem } from './utils'
const emit = defineEmits(['input', 'onFocus', 'change', 'blur', 'created'])
const model = defineModel()
const props = defineProps({
@ -34,7 +52,7 @@ const toolbarConfig = computed(() => {
'color', //
'bgColor', //
'bold',
'insertLink', //
'insertLink' //
]
}
if (props.needUploadImage) {
@ -51,6 +69,7 @@ const editorConfig = {
const store = useStore()
const token = _get(store, 'state.user.userInfo.token')
//
editorConfig.MENU_CONF['uploadImage'] = {
allowedFileTypes: ['image/jpeg', 'image/png'],
server: '/api/file/upload',
@ -65,7 +84,7 @@ editorConfig.MENU_CONF['uploadImage'] = {
customInsert(res, insertFn) {
const url = res.data.url
insertFn(url, '', '')
},
}
}
const setHtml = (newHtml) => {
@ -82,7 +101,8 @@ const onCreated = (editor) => {
emit('created', editor)
}
const onChange = (editor) => {
const editorHtml = editor.getHtml()
const editorHtml = replacePxWithRem(editor.getHtml())
curValue.value = editorHtml // html
emit('input', editorHtml) // v-model
}

View File

@ -0,0 +1,31 @@
// px 转换为 rem
const pxToRem = (px) => {
return `${(parseFloat(px) / 50).toFixed(2)}rem`
}
// 图片style的宽高改成rem
export const replacePxWithRem = (html) => {
const imgRegex = /<img[^>]*style=["'][^"']*\b(?:width|height):\s*\d+(\.\d+)?px[^"']*["'][^>]*>/gi
const styleRegex = /style="([^"]*)"/g
if (!imgRegex.test(html)) {
console.log('无需修改')
return html
}
const res = html.replaceAll(imgRegex, (imgHtml) => {
return imgHtml.replace(styleRegex, (match, content) => {
let styleContent = content
const pxRegex = /(width|height):\s*(\d+(\.\d+)?)px/g
styleContent = styleContent.replace(pxRegex, (pxMatch, prop, value) => {
return `${prop}: ${pxToRem(value)}`
})
return `style="${styleContent}"`
})
})
console.log('生成的结果', res)
return res
}

View File

@ -31,7 +31,9 @@ export const cleanRichTextWithMediaTag = (text) => {
if (!text) {
return text === 0 ? 0 : ''
}
const html = transformHtmlTag(text).replace(/<img([\w\W]+?)\/>/g,'[图片]').replace(/<video.*\/video>/g,'[视频]')
const html = transformHtmlTag(text)
.replace(/<img([\w\W]+?)\/>/g, '[图片]')
.replace(/<video.*\/video>/g, '[视频]')
const content = html.replace(/<[^<>]+>/g, '').replace(/&nbsp;/g, '')
return content

View File

@ -6,9 +6,12 @@
<div
:class="[
'tab-btn',
(['QuestionEditIndex', 'QuestionEditSetting', 'QuestionSkinSetting'].includes(
route.name
) &&
([
'QuestionEditIndex',
'QuestionEditSetting',
'QuestionSkinSetting',
'QuestionEditResultConfig'
].includes(route.name) &&
tab.to.name === 'QuestionEditIndex') ||
isActive
? 'router-link-active'

View File

@ -16,11 +16,11 @@
:label="item.title"
minWidth="200"
>
<template #header="scope">
<div class="table-row-cell">
<span
class="table-row-head"
@click="onPreviewImage"
@mouseover="onPopoverRefOver(scope, 'head')"
:ref="(el) => (popoverRefMap[scope.column.id] = el)"
v-html="item.title"
@ -46,8 +46,7 @@
ref="popover"
popper-style="text-align: center;font-size: 13px;"
:virtual-ref="popoverVirtualRef"
placement="top"
width="400"
placement="bottom"
trigger="hover"
virtual-triggering
>
@ -60,7 +59,6 @@
<script setup>
import { ref } from 'vue'
import { cleanRichText } from '@/common/xss'
import ImagePreview from './ImagePreview.vue'
const props = defineProps({
@ -106,7 +104,6 @@ const onPreviewImage = (e) => {
previewImageUrl.value = e.target.src
showPreviewImage.value = true
}
console.log(e.target.src)
}
</script>
@ -140,8 +137,10 @@ const onPreviewImage = (e) => {
overflow: hidden; /* 超出部分隐藏 */
text-overflow: ellipsis; /* 显示省略号 */
:deep(img) {
height: 23px;
width: auto;
height: 23px !important;
width: auto !important;
object-fit: cover;
margin-left: 5px;
}
:deep(p) {
display: flex;
@ -153,8 +152,3 @@ const onPreviewImage = (e) => {
font-size: 13px;
}
</style>
<style>
.el-popover p image {
max-width: 100%;
}
</style>

View File

@ -16,7 +16,6 @@ const props = defineProps<{
}>()
const visible = defineModel('visible')
</script>
<style lang="scss" scoped>
.v-enter-active,
@ -35,7 +34,7 @@ const visible = defineModel('visible')
top: 0;
right: 0;
bottom: 0;
background-color: rgba($color: #000000, $alpha: .4);
background-color: rgba($color: #000000, $alpha: 0.4);
z-index: 2024;
display: flex;
align-items: center;
@ -54,7 +53,6 @@ const visible = defineModel('visible')
}
}
.close-btn {
position: absolute;
right: 20px;

View File

@ -58,7 +58,7 @@ watch(
position: absolute;
top: 10px;
cursor: pointer;
z-index: 9999;
z-index: 999;
:deep(.el-radio-button__original-radio + .el-radio-button__inner) {
font-size: 12px;
height: 28px;