背景
一个现有的vue3项目,使用的是tsx,因为没有使用sfc,因此<style module>也无法使用。目前的方案是通过引入scss文件来进行样式处理,这样就会导致样式都是全局的,无法对样式进行scope,所以想要探索vue3 tsx的css modules方案。
在网上搜索了很长时间都没有到一个合适的方案,最后无意间在一个开源项目中发现他们使用的是@vanilla-extract/css,研究了一下发现在项目中正好可以使用。
vanilla-extract-css是什么
Write your styles in TypeScript (or JavaScript) with locally scoped class names and CSS Variables, then generate static CSS files at build time.
Basically, it’s “CSS Modules-in-TypeScript” but with scoped CSS Variables + heaps more.
一言以概之,就是用ts来写css moudles。
配置
vanilla-extract-c的配置非常简单,首先安装依赖。(相关代码都上传到了github上 vue3-css-modules)
npm install @vanilla-extract/css
根据打包器安装不同的plugin
我使用的是vite,安装配置如下
npm install --save-dev @vanilla-extract/vite-plugin
import { fileURLToPath, URL } from 'node:url'
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
export default defineConfig({
plugins: [vue(), vueJsx(), vanillaExtractPlugin({})],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
使用
css属性
export const myHeader = style({
fontSize: '16px',
fontWeight: 700,
lineHeight: 1.2,
color: 'yellow'
})
import { defineComponent } from 'vue'
import { myHeader } from '../styles/app.css'
export default defineComponent({
name: 'HomeView',
setup() {
return () => (
<>
<header class={myHeader}>my header</header>
</>
)
}
})
经过编译后的样式,如下
主题和变量
// 主题和变量
export const [themeClass, vars] = createTheme({
color: {
brand: 'blue',
text: 'red'
},
font: {
body: 'arial'
}
})
export const label = style({
color: vars.color.text,
// 伪类选择器
':hover': {
color: 'white'
}
})
import { defineComponent } from 'vue'
import { myHeader, themeClass, label } from '../styles/app.css'
export default defineComponent({
name: 'HomeView',
setup() {
return () => (
<>
<header class={myHeader}>my header</header>
<div class={themeClass}>
<span class={label}>my label</span>
</div>
</>
)
}
})
全局样式
// 全局样式
globalStyle('body', {
background: 'darkgray'
})
样式组合
// 样式组合
export const base = style({ padding: 12 })
export const primary = style([base, { background: vars.color.brand }])
export const secondary = style([base, { background: 'aqua' }])
总结
总结一下,@vanilla-extract/css 是一个用于在 TypeScript 和 JavaScript 中编写类型安全的 CSS 的库,它可以与 Vue 3 的 TSX 结合使用,提供了 CSS Modules 的功能。 使用 @vanilla-extract/css,你可以:
- 定义样式属性并将其应用于组件中的元素。
- 使用普通的 CSS 属性,如字体大小、颜色等。
- 使用变量和主题来定义样式,使样式更加灵活和可配置。
- 创建全局样式,对整个应用生效。
- 定义样式组合,将多个样式组合在一起使用。
这些功能可以让你在 Vue 3 TSX 项目中实现样式的模块化和作用域化,提高样式的可维护性和可扩展性。