前面写了一篇: CSS in JS = JSS , 这个库你知道吗? - 掘金
在评论里有人说:
同时还发了一个沸点:
你听说过 JSS 吗?在 JS 中写 CSS,感觉有点奇葩。 - 沸点 - 掘金
大家都很有才,视野很开阔~~
本瓜所在的项目组技术栈主要是 Vue2,平常又疏于 CSS 探究,对 JSX 里融合写 CSS 这种全面组件化的写法了解不多。
我现在是意识到了,这种写法其实早就有了,可参见阮一峰的这篇:CSS Modules 用法教程 - 阮一峰的网络日志
简而言之,代码组织形式类似如下,从 A 到 B 的过程:
// *.scss .item { display: flex; }
- A
// Simply import import './foo.scss'; const App = () => ( <div className="item"> {item} </div> )
- B
// import as a js module import styles from './foo.scss'; const App = () => ( <div className={styles.item}> {item} </div> )
编译出来的结果也不一样:
- A
<!-- Normal SCSS --> <div class="item">foo bar</div>
- B
<!-- SCSS with Class Module will have hash values suffixed to the class name --> <div class="item-35ada5">foo bar</div>
CSS in JS ,将样式也整合在模板组件里面,确实就像有人所说的:“分久必合、合久必分”。
JS in CSS
后来又了解到:
除了 CSS in JS,还有一种方向是 JS in CSS;尤雨溪在 Vue3.2 提出,目的是:让我们可以在 css 中使用 js 变量。SFC style CSS variable injection (new edition) by yyx990803 · Pull Request #231 · vuejs/rfcs
CSS in JS 是把 CSS 写在 JSX 模板中;
JS in CSS 是把 JS 变量写入 CSS 中;
想想我们在 Vue2 中,想动态控制样式,我们通常这样:
<template> <h1 :style="{opacity: opacity}">Vue</h1> </template> <script> export default { data () { return { opacity: 0 } }, mounted () { setInterval(() => { this.opacity >= 1 && (this.opacity = 0) this.opacity += 0.2 }, 300) } } </script> <style> h1 { color: rgb(65,184,131); } </style>
在 Vue3.2 中:
<template> <h1>Vue</h1> </template> <script> export default { data () { return { opacity: 0 } }, mounted () { setInterval(() => { this.opacity >= 1 && (this.opacity = 0) this.opacity += 0.2 }, 300) } } </script> <style> h1 { color: rgb(65,184,131); opacity: v-bind(opacity); } </style>
这个要借助 vite 编译:
npm init vite-app vars npm i npm run dev
然后就可以看到效果了
再补充一个颜色选择器的例子
<template> <div class="Example"> <div class="area"> <div class="form"> <label>Select Color (SCSS)</label> <input type="color" v-model="themeColors.bgColor" /> </div> <div class="preview"> <span>{{ themeColors.bgColor }}</span> <div class="customColor"></div> </div> </div> </div> </template> <script> import { ref } from "vue"; export default { setup() { const themeColors = ref({ bgColor: '' }) return { themeColors }; }, }; </script> <style lang="scss"> .Example { $customColor: v-bind('themeColors.bgColor'); .customColor { background: $customColor; width: 100px; height: 50px; } } </style>
小结
不管是 CSS in JS 还是 JS in CSS,总之都想整合 JS 和 CSS 的能力,梳理一个新的模板规范。
后面还会怎么变?拭目以待。
- 为什么是 v-bind?有更多兴趣的可以看下 SFC style CSS variable injection (new edition) by yyx990803 · Pull Request #231 · vuejs/rfcs 尤大在这个 issues 下对大家关于自定义写法上建议的回答。