当前位置: 首页 > 工具软件 > UnoCSS > 使用案例 >

使用unocss进行css原子化开发

莫翰藻
2023-12-01

主要利用unocss的preset,制定自定义rule,配合正则表达式实现简单类名

1 设置flex属性

import type { Preset } from 'unocss

const directionAbbr = {
  col: 'column',
  colr: 'column-reverse',
  row: 'row',
  rowr: 'row-reverse',
}
//主轴方向
const justifyAbbr = {
  center: 'center',
  start: 'flex-start',
  end: 'flex-end',
  between: 'space-between',
  around: 'space-around',
  evenly: 'space-evenly',
}

//交叉轴方向
const alignAbbr = {
  center: 'center',
  start: 'flex-start',
  end: 'flex-end',
  baseline: 'baseline'
}

export function presetFlex( config?: { prefix?:string } ):Preset {
	const _config = { prefix: config?.prefix || 'sm' }
	const direction = Reflect.ownKeys(directionAbbr).join('|')
  	const justify = Reflect.ownKeys(justifyAbbr).join('|')
  	const align = Reflect.ownKeys(alignAbbr).join('|')
	
	const reg1 = new RegExp(
		`^${_config.prefix}-flex-(${direction})$`	
	)
	const reg2 = new RegExp(
		`^${_config.prefix}-flex-(${direction})-(${justify})-(${align})$`	
	)
	
	return {
		name: 'unocss-preset-flex',
		rules: [
			[
				`${_config.prefix}-flex`, {
					display: 'flex',	
				}	
			],
			[
				reg1, 
				(_,d)=>{
					return {
						display: 'flex',
						'flex-direction': directionAbbr[d]	
					}	
				}
			],
			[
				reg2,
				(_,d,j,a) => {
					return {
						display: 'flex',
						'flex-direction': directionAbbr[d],
						'justify-content': justifyAbbr[j],
						'align-items': alignAbbr[a]
					}	
				}
			]		
		]
	}
}

2 设置字体大小

import type { Preset } from 'unocss'

interface Theme {
	xs: string,
	s: string,
	m: string,
	l: string,
	xl: string,
	[x:string]: any
}

export function presetFont (config?: {
	varPrefix?: string,
	theme?: Partial<Theme>,
}):Preset {
	const _config = {
		prefix: config?.varPrefix || 'f',
		theme: {},
		...config
	}
	
	const theme = {
		xs: '0.8rem',
		s: '0.9rem',
		m: '1rem',
		l: '1.1rem',
		xl: '1.2rem'	
	}
	const resolveVar = (name:string) => {
		const prefix = _config.prefix
		return `--${prefix? `${prefix}-`: ''}${name}`
	}
	
	return {
		name: 'unocss-preset-font',
		theme,
		preflights: [
			{
				getCSS() {
					let ruleStr = ''
					for(const key in theme){
						if(Object.prototype.hasOwnproperty.call(theme,key)){
							ruleStr += _config.prefix+ ':' + theme[key] + ';'	
						}	
					}
					return `:root{
						${ruleStr}	
					}`
				}	
			}
		],
		rules: [
			[
				/^f-(\d?([A-Za-z])+)$/,
				([,w]) => {
					return {
						'font-size': `var(${resolveVar(w)})`	
					}	
				}
			],
			[
				/^f-(\d?)$/,
				([,d]) => {
					return {
						'font-size': `${d}rem`	
					}	
				}	
			]	
		]	
	}

}

3 设置第二个元素开始的间距

const acronym = {
  ml: 'margin-left',
  mr: 'margin-right',
  mt: 'margin-top',
  mb: 'margin-bottom',
  ma: 'margin',

  mtb: [ 'margin-top',  'margin-bottom' ],
  mlr: [ 'margin-left',  'margin-right'],
  

  pl: 'padding-left',
  pr: 'padding-right',
  pt: 'padding-top',
  pb: 'padding-bottom',
  pa: 'padding',

  ptb: [ 'padding-top',  'padding-bottom' ],
  plr: [ 'padding-left',  'padding-right'],

} as const


export function presetGap(config?: {
	varPrefix?: string,
	theme?: Partial<Theme>,
}):Preset {
	const _config = {
		prefix: config?.varPrefix || 'f',
		theme: {},
		...config
	}
	
	const theme = {
		xs: '0.8rem',
		s: '0.9rem',
		m: '1rem',
		l: '1.1rem',
		xl: '1.2rem'	
	}
	const resolveVar = (name:string) => {
		const prefix = _config.prefix
		return `--${prefix? `${prefix}-`: ''}${name}`
	}
	return {
		name: 'unocss-preset-gap',
		theme,
		preflights: [
	      {
	        getCSS () {
	          let ruleStr = ''
	          for (const key in theme) {
	            if (Object.prototype.hasOwnProperty.call(theme, key)) {
	              ruleStr += resolveVar(key) + ':' + theme[key] + ';'
	            }
	          }
	          return `:root{
	            ${ruleStr}
	          }`
	        },
	      },
	    ],
	    variants: [
	    	(matcher) => {
	    		if(!(matcher.startWith('sub-')||matcher.startWith('sub:') )){
	    			return matcher	
	    		}	
	    		return {
	    			matcher: matcher.slice(4),
	    			selector: s => `${s} > * + * `	
	    		}
	    	}	
	    ],
	    rules: [
			[
				/^(mt|mb|mr|ml|ma|pt|pb|pr|pl|pa|mtb|mlr|ptb|plr)-(\d?([A-Za-z]|-)+)$/,
				([,a, w]) => {
					const props  = acronym[a]
					const rule = `${resolveVar(w)}`,
					if(Array.isArray(props)){
						return props.reduce((p,c)=>(p[c]=rule,p),{})	
					}	
					return {
						[props]: rule	
					}
				}
			]
			
		]
			
	}
}
 类似资料: