import {nextTick, watch, onMounted, type Ref} from 'vue' /** * 图片样式处理 Composable * 用于强制处理 v-html 内容中的图片样式 */ export const useImageStyles = ( contentRef: Ref | (() => 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 } }