假如我有一个需求,必须通过 js 执行动画,还得让 css 去配合。
拿一个简单却不太恰当的例子来说:opacity‘一闪一闪’效果的实现。传统Vue必须要利用“动态style”。

<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(65184131);
}
</style>

但是在 vue3.2 中,尤大提出了一个概念:Js in Css。它让我们可以在 css 中使用 js 变量,更好的控制动画的轨迹!从而达到“js向css传值”的效果。

使用前需注意:本规则依托于vite,除此之外需先引入vars
vars

<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 vars="{ opacity }"> <!-- 绑定css中接收的变量 -->
h1 {
	color: rgb(65184131);
	opacity: var (--opacity);
}
</style>

那 css 怎么向 js 传参?比如“主题跟随系统变化”:

@media (prefers-color-scheme: dark) {
	/* 黑暗模式,深色主题 */
}

@media (prefers-color-scheme: light) {
	/* 浅色主题 */
}

比如“响应式布局中判断pc还是移动端”:

@media (any-hover: none) {
	/* 设备不支持hover事件 */
}

等等。
这些情况大多是由于页面的变化要导致一些感官(UI)和操作上的改变。而 css 和 js 的“边界一致性”无法保证。

拿上面的any-hover来说,js 中就没有支持相关的 API。
除此之外,通常还有人这么做:

@media screen and (max-width: 480px) {
	/* 小屏幕宽度下的响应式布局 */
}

这倒是可以直接在 js 中对screen.width进行if操作。但是假如一段时间之后,发现这个临界宽度有问题(比如手机横屏的时候),这时候但凡少修改一方,就会导致“bug”的产生。实为不智。

但是我们可以通过

  1. content伪元素内容传参

例如:

@media (any-hover: none) {
    body::before {
        content: 'hoverNone';
        display: none;
    }
}

此时就可以通过JS代码获取body伪元素传递的信息是什么了:

var strContent = getComputedStyle(document.body, '::before').content;
// strContent结果是'none'则表示支持hover
// strContent结果是'"hoverNone"'则表示不支持hover经过,需要换成click事件

这样,我们就可以根据::before, ::after伪元素配合content属性,获知CSS中传递的信息了。
这种传参方式的优点在于兼容性相对较好,但是不足却也很明显,那就是我们传递的参数值的数量是有限的,如果我们想一次性传多个值,就有些捉襟见肘,此时可以试试下面这种方法,借助CSS自定义属性。

  1. CSS自定义属性(CSS变量)传参

还是拿“跟随系统改变主题色”来说,有了CSS自定义属性(CSS变量),黑暗模式和浅色模式的开发和维护工作就变得相对容易很多。

:root {
    --mode: 'unknown';
}
@media (prefers-color-scheme: dark) {
    /* 黑暗模式 */
    :root {
         --mode: 'dark';
         --colorLink: #bfdbff;
         --colorMark: #cc0000;
         --colorText: #ffffff;
         --colorLight: #777777;
    }
}
@media (prefers-color-scheme: light) {
    /* 浅色主题 */
    :root {
         --mode: 'light';
         --colorLink: #34538b;
         --colorMark: #cc0000;
         --colorText: #000000;
         --colorLight: #cccccc;
    }
}

JS 同样可以检测到自定义属性:

var mode = getComputedStyle(document.documentElement).getPropertyValue('--mode').trim();
// mode结果是'"dark"'则表示黑夜主题,深色模式,黑暗风格,护眼模式。

使用CSS自定义属性传统的好处是非常灵活,我们可以定义很多很多的变量都可以。而且目前我们也没有任何必要担心兼容性的问题。

Logo

前往低代码交流专区

更多推荐