图片样式处理工具

This commit is contained in:
WindowBird 2025-10-13 13:51:40 +08:00
parent e35a5e0577
commit 30aa21e72c
2 changed files with 130 additions and 27 deletions

View File

@ -1,5 +1,6 @@
<script lang="ts" setup>
import {computed} from "vue";
import {useImageStyles} from '~/composables/useImageStyles';
//
interface Props {
@ -41,41 +42,28 @@ const reloadPage = () => {
}
}
// 使 composable
const {initImageStyles} = useImageStyles(
() => props.articleData.content,
'.article-content',
{
maxWidth: '100%',
margin: '15px 0',
display: 'block',
boxSizing: 'border-box'
}
)
onMounted(() => {
// CSS
loadCSSFiles()
// JavaScript
loadJSFiles()
//
nextTick(() => {
forceImageStyles()
})
})
//
const forceImageStyles = () => {
if (typeof document !== 'undefined') {
const images = document.querySelectorAll('.article-content img')
images.forEach((img: any) => {
//
img.style.maxWidth = 'calc(100% - 20px)'
img.style.height = 'auto'
img.style.width = 'auto'
img.style.display = 'block'
img.style.margin = '15px 0'
img.style.boxSizing = 'border-box'
})
}
}
//
watch(() => props.articleData.content, () => {
nextTick(() => {
forceImageStyles()
})
}, {deep: true})
//
initImageStyles()
const loadJSFiles = () => {
const jsFiles = [

View File

@ -0,0 +1,115 @@
import {nextTick, watch, onMounted, type Ref} from 'vue'
/**
* Composable
* v-html
*/
export const useImageStyles = (
contentRef: Ref<string> | (() => string),
containerSelector: string = '.article-content',
options: {
maxWidth?: string
margin?: string
display?: string
boxSizing?: string
} = {}
) => {
// 默认配置
const defaultOptions = {
maxWidth: 'calc(100%-0px)',
margin: '15px 0',
display: 'block',
boxSizing: 'border-box',
...options
}
/**
*
*/
const forceImageStyles = () => {
if (typeof document === 'undefined') return
const images = document.querySelectorAll(`${containerSelector} img`)
images.forEach((img: any) => {
// 强制设置样式
img.style.maxWidth = defaultOptions.maxWidth
img.style.height = 'auto'
img.style.width = 'auto'
img.style.display = defaultOptions.display
img.style.margin = defaultOptions.margin
img.style.boxSizing = defaultOptions.boxSizing
})
}
/**
*
*/
const processImageStyles = () => {
nextTick(() => {
forceImageStyles()
})
}
/**
*
*/
const initImageStyles = () => {
// 组件挂载时处理
onMounted(() => {
processImageStyles()
})
// 监听内容变化
if (typeof contentRef === 'function') {
// 如果是函数,直接监听
watch(contentRef, () => {
processImageStyles()
}, {deep: true})
} else {
// 如果是 Ref监听其值
watch(contentRef, () => {
processImageStyles()
}, {deep: true})
}
}
/**
*
*/
const triggerImageStyles = () => {
processImageStyles()
}
return {
forceImageStyles,
processImageStyles,
initImageStyles,
triggerImageStyles
}
}
/**
* -
* @param containerSelector
* @param options
*/
export const useSimpleImageStyles = (
containerSelector: string = '.article-content',
options: {
maxWidth?: string
margin?: string
display?: string
boxSizing?: string
} = {}
) => {
const {forceImageStyles, processImageStyles} = useImageStyles(
() => '', // 空函数,不监听内容变化
containerSelector,
options
)
return {
forceImageStyles,
processImageStyles
}
}