摘要

在单文件组件样式中支持使用组件状态驱动的 CSS 变量( CSS 自定义属性)。

基础示例

<template>
<div class="text">hello</div>
</template> <script>
export default {
data() {
return {
color: 'red',
font: {
size: '2em',
},
}
},
}
</script> <style>
.text {
color: v-bind (color); /* expressions (wrap in quotes) */
font-size: v-bind ('font.size');
}
</style>

动机

Vue SFC 样式提供了直接的 CSS 搭配和封装,但它是纯粹的静态的 —— 这意味着到目前为止,我们没有能力在运行时根据组件的状态动态更新样式。

现在,随着大多数现代浏览器支持原生 CSS 变量,我们可以利用它来轻松连接组件的状态和样式。

设计细节

SFC 中的标签现在支持一个自定义 CSS 函数 v-bind

<!-- in Vue SFC -->
<style>
.text {
color: v-bind (color);
}
</style>

正如预期的那样,这将把声明的值绑定到组件状态的属性上,reactively.color color

该函数内部可以支持任意的 JavaScript 表达式,但由于 JavaScript 表达式可能包含在 CSS 标识符中无效的字符,因此在大多数情况下需要用引号来包裹它们:v-bind

.text {
font-size: v-bind ('theme.font.size');
}

当检测到这种 CSS 变量时,SFC 编译器将执行以下操作:

  1. 重写到一个带有哈希变量名称的本机。上面的内容将被改写为:v-bind () var ()

    .text {
    color: var (--6b53742-color);
    font-size: var (--6b53742-theme_font_size);
    }

    请注意,hash 将应用于所有情况,无论标签是否有范围。这意味着注入的 CSS 变量不会意外地泄漏到子组件中。

  2. 相应的变量将作为内联样式被注入到组件的根元素中。对于上面的例子,最终渲染的 DOM 将看起来像这样:

    <div style="--6b53742-color:red;--6b53742-theme_font_size:2em;" class="text">
    hello
    </div>

    注入是响应式的 ——所以如果组件的属性发生变化,注入的 CSS 变量将被相应地更新。这种更新是独立于组件的模板更新的,所以对一个纯 CSS 的响应式属性的改变不会触发模板的重新渲染。

编译细节

  • 为了注入 CSS 变量,编译器需要生成并注入如下代码到组件的 setup ()

    import { useCssVars } from 'vue'
    
    export default {
    setup() {
    //...
    useCssVars(_ctx => ({
    color: _ctx.color,
    theme_font_size: _ctx.theme.font.size,
    }))
    },
    }

    ... 这里,运行时帮助器设置了一个将变量响应性地应用到 DOM.useCssVars watchEffect 上。

  • 该编译策略要求脚本编译时首先对标签内容进行简单的重码解析,以确定要暴露的变量列表。然而,这个解析阶段不会像基于 AST 的完整解析 <style> 那样耗费开销。

  • 在生产中,变量名可以被进一步 hash,以减少 CSS 的占用。

    .text {
    color: var (--x3b2fs2);
    font-size: var (--29fh29g);
    }

    相应的生成的 JavaScript 代码将相应地使用相同的哈希值。

采用策略

这是一个完全向后兼容的新功能。然而,我们应该明确指出,它依赖于本地的 CSS 变量,所以用户需要了解浏览器的支持范围。

实践

在 script 中声明两个响应式的属性,分别是 wallpaperBlurwallpaperMaskwallpaperBlur 表示壁纸的模糊程度, wallpaperMask 表示遮罩的透明度。通过 v-bind 将它们应用到 style,这意味着当我们在 script 中改变这两个值时,样式会响应更改。

// script
const wallpaperBlur = ref('0px')
const wallpaperMask = ref('rgba(0, 0, 0, 0)')
// style
.wallpaper {
filter: blur(v-bind(wallpaperBlur));
bottom: calc(v-bind(wallpaperBlur) * -2);
left: calc(v-bind(wallpaperBlur) * -2);
right: calc(v-bind(wallpaperBlur) * -2);
top: calc(v-bind(wallpaperBlur) * -2);
.wallpaper-image {
transition: background-image 0.6s, background-color 0.4s;
}
.wallpaper-mask {
background-color: v-bind(wallpaperMask);
}
}

提示

绑定恰当的属性

在上面的例子中,你可能想到到更改遮罩的透明度仅需要声明一个 0-1 的数字,之后在 style 中这样写:

.wallpaper-mask {
background-color: rgba(0, 0, 0, v-bind(wallpaperMask));
}

上文已经提到在编译阶段会将 style 中的 v-bind 改写为 CSS 变量的形式,上面的代码会被改写为这样:

.wallpaper-mask {
background-color: rgba(0, 0, 0, var (--[hash]-wallpaper_mask));
}

rgba(0, 0, 0, var (--[hash]-wallpaper_mask)) 在 CSS 中是无法被解析的。所以这就是为什么将 wallpaperMask 的初始值声明为 rgba(0, 0, 0, 0) 的原因,这是需要十分注意的一点,CSS 中还有许多类似的情况。

注意 style 的更新

在设计细节中提到相应的变量将作为内联样式被注入到组件的根元素中。最终渲染的 DOM 将看起来像这样:

<div style="--6b53742-color:red;--6b53742-theme_font_size:2em;"></div>

当你在 <script> 中改变 <style> 中绑定的属性时,内敛样式中的 CSS 变量将会响应更改。但是,并不能单独更新内敛样式其中的一个 CSS 变量,这意味着更新一个组件中的任意一个“动态样式”,都将引起根组件中的内敛样式全部更新。当 style 属性的值包含大量 CSS 变量时,你需要考虑重新组织组件。因为编译生成的 CSS 变量都将作为内联样式被注入到组件的根元素中,我们无法控制这种行为,将一个引起更新的 CSS 变量和其他 CSS 变量解耦。

试想这种情况, style 中编译生成的 CSS 变量中包含一个其值为庞大的 base64 的 CSS 变量。当更新该组件中其他 CSS 变量时,整个 style 都将更新,这将带来额外的硬件开销。我们需要将这个生成 base64 CSS 变量的组件单独抽离,以使该 CSS 变量注入到该组件的根元素,不收其他 CSS 变量更新影响。

参考资料

SFC style CSS variable injection的更多相关文章

  1. 引人瞩目的 CSS 变量(CSS Variable)

    这是一个令人激动的革新. CSS 变量,顾名思义,也就是由网页的作者或用户定义的实体,用来指定文档中的特定变量. 更准确的说法,应该称之为 CSS 自定义属性 ,不过下文为了好理解都称之为 CSS 变 ...

  2. Node聊天程序实例05:index.html和style.css

    作者:vousiu 出处:http://www.cnblogs.com/vousiu 本实例参考自Mike Cantelon等人的<Node.js in Action>一书. index. ...

  3. 可否控制<link type=text/css rel=stylesheet href=style.css>

    本篇文章主要介绍了"可否控制<link type=text/css rel=stylesheet href=style.css> ", 主要涉及到可否控制<lin ...

  4. WordPress主题开发:style.css主题信息标记

    在最简单的情况下,一个WordPress主题由两个文件构成: index.php ------------------主模版 style.css -------------------主样式表 而且s ...

  5. 跨平台移动开发 Xuijs超轻量级的框架Style CSS属性用法

    PhoneGap里面推荐使用的超轻量级的框架 Style CSS属性用法 设置css属性:setstyle 通过ID设置css属性 x$('#top1').setStyle('color', '#DB ...

  6. CSS变量(CSS variable)

    使用 CSS 变量编写你的样式代码 基本使用: 1. --variable: <declaration-value> 2. <css-attribute>: var(--var ...

  7. wordpress后台编辑如何显示定义的`style.css`样式

    wordpress后台编辑如何显示定义的style.css样式 由于公司官网采用wordpress进行搭建,但是却又自己设计页面,无奈主题只能自行构建了,直接修改wordpress自带的主题进行修改. ...

  8. [Coding Style] CSS coding style

    CSS coding style Note 结合实际工作中的规范和推荐大家使用的CSS书写规范.顺序这篇文章整合而成 Navigation CSS 书写顺序 CSS 常用文件命名 CSS 常用命名规范 ...

  9. [TypeStyle] Style CSS pseudo elements with TypeStyle

    Just like pseudo-classes, pseudo-elements are added to selectors but instead of describing a special ...

随机推荐

  1. 人工智能训练云燧T10

    人工智能训练云燧T10 基于邃思芯片打造的面向云端数据中心的人工智能训练加速产品,具有高性能.通用性强.生态开放等优势,可广泛应用于互联网.金融.教育.医疗.工业及政务等人工智能训练场景. 超强算力 ...

  2. GPU—加速数据科学工作流程

    GPU-加速数据科学工作流程 GPU-ACCELERATE YOUR DATA SCIENCE WORKFLOWS 传统上,数据科学工作流程是缓慢而繁琐的,依赖于cpu来加载.过滤和操作数据,训练和部 ...

  3. CPU的自动调度矩阵乘法

    CPU的自动调度矩阵乘法 这是一个有关如何对CPU使用自动调度程序的文档. 与依靠手动模板定义搜索空间的基于模板的autotvm不同,自动调度程序不需要任何模板.用户只需要编写计算声明,而无需任何调度 ...

  4. 使用js获取checkbox控件在GridView中的第几行

    这次的知识点是如何使用js获取checkbox控件所在的是第几行!!! 我们可以使用 JavaScript 中自带的 rowIndex 和 cellIndex 来获取行和列的键值 (从0开始) 这两个 ...

  5. eclipse 新建项目不可选择Java Project 解决方法

    解决方法一: 鼠标点击file-new-other,弹出选项框,选中java project,点击next,接下来就是正常创建java protect的流程了,这个虽然也可以解决,但每次新建java项 ...

  6. selenium-python元素定位技巧(一)

    在python-selenium元素定位中,有很多小技巧,在此记录总结 技巧一.尽量不要用可见的文本去定位 尽量不要用可见的文本去定位(特别是支持国际化的软件-比如禅道),因为一旦切换语言后,使用该方 ...

  7. Centos7 安装 Keepalived

    目标: Keeplaived 简单模拟测试一下Nginx 故障切换前言:C7 默认的 1.3.5 似乎有点问题,改装 keepalived-2.0.7 1:安装 Nginx 和确认 (略)2:安装配置 ...

  8. Mysql慢SQL分析及优化

    为何对慢SQL进行治理 从数据库角度看:每个SQL执行都需要消耗一定I/O资源,SQL执行的快慢,决定资源被占用时间的长短.假设总资源是100,有一条慢SQL占用了30的资源共计1分钟.那么在这1分钟 ...

  9. Java进阶 | Proxy动态代理机制详解

    一.Jvm加载对象 在说Java动态代理之前,还是要说一下Jvm加载对象的过程,这个依旧是理解动态代理的基础性原理: Java类即源代码程序.java类型文件,经过编译器编译之后就被转换成字节代码.c ...

  10. external-provisioner源码分析(3)-组件启动参数分析

    更多ceph-csi其他源码分析,请查看下面这篇博文:kubernetes ceph-csi分析目录导航 external-provisioner源码分析(3)-组件启动参数分析 本文将对extern ...