当前位置: 首页 > Web前端 > HTML

提升组件库通用能力——NutUI在线主题定制功能探索

时间:2023-03-28 00:34:28 HTML

开发背景NutUI作为京东风格的组件库,已经具备H5和多端小程序开发能力。随着业务的不断发展,组件库的应用场景也越来越广。供公司内外技术、财务、物流等多个大型团队使用时,虽然单个京东APP视觉可以一键换肤,但对于更多个性化的定制需求(组件级样式、规格、尺寸),等等))近千行的主题风格变量对于开发者来说是非常沉重的。为了改善开发体验,提高开发者效率,强化换肤功能,实现“组件级定制”功能迫在眉睫。设计目标允许用户在开发阶段切换不同主题风格的皮肤,也允许开发者直接修改指定组件的风格以满足不同设计风格的移动业务场景。效率提升官网将提供多套主题供开发者选择。同时,开发者还可以基于多套主题进行实时编辑修改。完成后,下载配置变量,在项目中应用,非常好用。只需1分钟即可完成一次全局样式配置。与该场景下的需求开发相比,速度更快,可以降低开发成本。组件粒度主题定制配置层分为全局基础变量和组件基础变量。开发者可以全局修改,比如组件库的全局主题颜色、字体等样式。组件层的配置可以更细化。比如成功的Button按钮的圆角边框尺寸可以展开。现阶段官方会提供一些优质的主题整合到官网中。对于社区开发者,开发团队,如果你的团队自定义样式主题文件的受众面很广,可以联系我们将你的主题构建到官方npm包中,让更多的开发者受益如何使用视频教程NutUI一分钟为开发者快速在线定制主题https://www.bilibili.com/video/BV1fi4y1D7qb1。打开在线配置网站,根据下图修改预览下载。2.本地项目配置修改本地项目webpack或vite的配置文件。将下载的custom_theme.sass文件集成到assets/styles/custom_theme等项目中。Sassvite构建工具示例vite.config//https://vitejs.dev/config/exportdefaultdefineConfig({//...css:{preprocessorOptions:{scss:{//默认京东APP10.0主题>@import"@nutui/nutui/dist/styles/variables.scss";//京东科技主题>@import"@nutui/nutui/dist/styles/variables-jdt.scss";additionalData:`@import"./assets/styles/custom_theme.scss";@import"@nutui/nutui/dist/styles/variables.scss";`}}}})webpack构建工具示例{test:/\.(sa|sc)ss$/,使用:[{loader:'sass-loader',options:{//默认京东APP10.0主题>@导入“@nutui/nutui/dist/styles/variables.scss”;//京东科技主题>@import"@nutui/nutui/dist/styles/variables-jdt.scss";data:`@import"./assets/styles/custom_theme.scss";@import"@nutui/nutui/dist/styles/variables.scss";`,}}]}芋头小程序使用实例修改scss文件在config/index.js文件中配置以实现全局覆盖,例如:constpath=require('path');constconfig={deviceRatio:{640:2.34/2,750:1,828:1.81/2,375:2/1},sass:{resource:[path.resolve(__dirname,'..','src/assets/styles/custom_theme.scss')],//默认京东APP10.0主题>@import"@nutui/nutui-taro/dist/styles/variables.scss";//京东科技主题>@import"@nutui/nutui-taro/dist/styles/variables-jdt.scss";data:`@import"@nutui/nutui-taro/dist/styles/variables.scss";`},//...实现原理分析整个组件库的主题定制模块。实现可以分为两个方向,一个是内部组件库设计(供开发者配置各个样式变量),一个是在线配置官网(供开发者使用)捷修改),然后按照设计图来解释组件库的内部设计从源码的内部样式文件夹开始。有多个variables.scss和variables-jdt.scss文件对应不同的官方主题。每个主题的全局variables.scss文件实际上在内部遵循标准规则。存储通用样式变量和各组件的样式变量,如下所示//------basebegin--------//Primarycolor$primary-color:#fa2c19!default;$primary-color-end:#fa6419!default;//辅助颜色$help-color:#f5f5f5!default;//常规标题文本$title-color:#1a1a1a!default;//副标题$title-color2:#666666!default;//辅助内容$text-color:#808080!default;//...//Font$font-size-0:10px!default;$font-size-1:12px!default;$font-size-2:14px!default;$font-size-3:16px!default;$font-size-4:18px!default;$font-weight-bold:400!default;$font-size-small:$font-size-1!default;$font-size-base:$font-size-2!default;$font-size-large:$font-size-3!default;$line-height-base:1.5!default;//--------baseend--------//button$button-border-radius:25px!default;$button-border-width:1px!default;$button-default-bg-颜色:$white!default;$button-default-border-color:rgba(204,204,204,1)!default;$button-default-color:rgba(102,102,102,1)!default;//...//icon//...这里啰嗦一句,可以看到每行后面都有一个!default,这个必不可少,如果不是,开发者本地项目不能覆盖这个变量https://www.sass.hk/docs/#t6-9小贴士:可以在变量末尾加上!default来给已经有的变量赋值没有通过!default声明赋值,此时,如果变量已经赋值,则不会重新赋值,但如果变量还没有赋值,则会被赋新值对于每个组件内部,比如button/index.scss下,高度是这样引用的:$button-default-height;.nut-button{position:relative;显示:内联块;伸缩收缩:0;高度:$按钮默认高度;//...}实际上,当最终的组件库被构建成一个npm包时,主题的全局变量.scss和其他主题文件就暴露给了开发者,然后开发者根据需要替换里面的样式变量到要求。至此组件库内部的主题定制实现了可视化配置。官网源码预览:https://github.com/jdf2e/nutui/tree/theme/src/sites/doc/components/ThemeSetting整体实现流程如下,然后依次解释Splitvariables.scss源文件通过组件配置数据+正则匹配得到这样的数据结构button-border-radius:25px!default;$button-border-width:1px!default;//...//图标//...[{name:'Base',lowerCaseName:'base',key:'$primary-color',rawValue:'#fa2c19',computedRawValue:''}{name:'Base',lowerCaseName:'base',key:'$primary-color-end',rawValue:'#fa6419',computedRawValue:''}//...{name:'Button',lowerCaseName:'button',key:'$button-border-width',rawValue:'1px',computedRawValue:''}{name:'按钮',lowerCaseName:'button',key:'$button-border-radius',rawValue:'25px',computedRawValue:''}//{name:'components1',lowerCaseName:'components1',key:'$components1-border}-radius',rawValue:'xx',computedRawValue:''}//...]constfindStyle=(componentName:string)=>{//https://raw.githubusercontent.com/jdf2e/nutui/next/src/packages/styles/variables.scss//varpattern=/\$button.*;/g;varp=newRegExp(`\\$${componentName}.*;`,'g');让parray:any[]=varcss.match(p)||[];//需要包含换行符letcommonetns=parray.map((item)=>{letcArray=item.split(':');letname=cArray[0],value:string=cArray[1].replace('!default;','').trim();return{name:componentName,key:name,rawValue:value,computedRawValue:''}});}components.map(item=>{findStyle(item.name)});接下来根据不同组件显示组件下所有变量,监控组件切换或编辑,实时编译constcssText=computed(()=>{constvariablesText=store.variables.map(({key,value})=>`${key}:${value}`).join(';');缓存样式=缓存样式||提取样式(store.rawStyles);return`${variablesText};${cachedStyles}`;});constformItems=computed(()=>{constname=route.path.substring(1);returnstore.variables.filter(({lowerCaseName})=>lowerCaseName===name);});watch(()=>cssText.value,(css)=>{clearTimeout(timer);timer=setTimeout(()=>{constSass=(windowasany).Sass;letbeginTime=newDate().getTime();console.log('sass编译开始',beginTime);Sass&&Sass.compile(css,async(res:Obj)=>{awaitawaitIframe();constiframe=window.frames[0]asany;if(res.text&&iframe){console.log('sass编译成功',newDate().getTime()-beginTime);if(!iframe.__styleEl){conststyle=iframe.document.createElement('style');style.id='主题';iframe.__styleEl=样式;iframe.__styleEl.innerHTML=res.text;iframe.document.head.appendChild(iframe.__styleEl);}else{console.log('sass编译失败',newDate().getTime()-beginTime);console.error(res);}if(res.status!==0&&res.message){console.log(res.message);}});},300);},{immediate:true});下载配置变量操作由于变量文件有近千行,以后可能会更大,所以直接使用Blob文件流生成下载downloadScssVariables(){if(!store.variables.length){返回;}让温度='';constvariablesText=store.variables.map(({name,key,value})=>{letcomment='';if(temp!==name){temp=name;comment=`\n//${name}\n`;}返回评论+`${key}:${value};`;}).join('\n');download(`//NutUI主题定制\n${variablesText}`,'custom_theme.scss');}functiondownload(content:string,filename:string){consteleLink=document.createElement('a');eleLink.download=文件名;eleLink.style.display='无';constblob=newBlob([内容]);eleLink.href=URL.createObjectURL(blob);document.body.appendChild(eleLink);eleLink.click();document.body.removeChild(eleLink);}总结文章详细介绍了NutUI的“主题自定义”和“组件级样式自定义”功能的实现机制。“主题定制”可以实现简单的颜色切换,“组件级样式定制”功能更强大。通过暴露组件的样式变量,开发者几乎可以修改自己想要的设计样式(组件大小、字体、边距)。通过强大的主题定制,组件库的使用不局限于原设计者的设计范围,可以灵活扩展组件,使组件库的应用范围更广,可以满足更广泛的业务场景。期待您的使用和反馈??~