vue组件 css样式中使用 js变量
最近用vue做后台管理模块, 需要在css中引用用 js 的变量来动态的设置 elementui组件里边的css . 从网上找了很多方法, 经测试有一些不好用(具体原因还没查),
找到了如下方法测试好用, 这里记录一下 , 以便查询
<template>
<div>
<component is="style">
:root {
--bg-color: {{bgColor}};
--box-size: {{boxSize}};
}
</component>
<el-select :class="'myselect'"></el-select>
</template>
</div>
<script>
export default {
data () {
return {
bgColor: "white",
boxSize: "30px"
}
}
}
</script>
<style lang="scss">
.myselect{
color: var(--bg-color)
}
</style>
参考内容:
(。・v・。)文章目录
一、参考
二、问题描述
三、第一个方案——动态 style 标签
第一个例子
第二个例子
四、第二个方案——CSS 变量
4.1 快速入门 CSS 变量 ,var() 函数
4.2 快速入门案例
4.3 Vue 修改CSS变量案例
五、总结
一、参考
js修改style样式_Vue 动态样式黑魔法(超实用)
CSS 变量教程 阮一峰
二、问题描述
工作中使用 elementUI 的scrollbar 组件,例如 <el-scrollbar wrap-class="demo-scrollbar-wrap-2">,只能让 wrap-class设置具体的类名,当浏览器窗口发生变化的时候,类名没有改变,则对应的样式也没有改变,导致scroll无法做到“自适应窗口变化”的效果众所周知,Vue 中动态绑定样式是用 :style,或者是动态绑定 :class class,不同的 class 样式提前写好且不一样。
但是如果是 ::after伪元素或者要改变的样式用 js 计算很复杂但是用 CSS 计算很简单的话,这种方法就略显得麻烦。有没有什么办法能用 Vue 直接改变 CSS,而不用这一套绑定的办法呢。答案是有的!这里给出两个实现方案。
三、第一个方案——动态 style 标签
其实早在 Vue 0.x 和 1.x 版本这样做一度很流行(和这种升级的方案略有不同)第一个例子
<template> <div> <component is="style"> .foo[data-id="{{ uniqueId }}"] { color: {{ color }}; } .foo[data-id="{{ uniqueId }}"] .bar { text-align: {{ align }} } </component> <div class="foo" :data-id="uniqueId"> <div class="bar"> hello world </div> </div> </div> </template> <script> export default { computed: { uniqueId() { return 一个独一无二的id; // 是因为这样生成的 style 没有 scoped,别的组件也能使用这个样式 }, color() { return someCondition ? 'red' : '#000'; }, align() { return someCondition ? 'left' : 'right'; } } } </script>
第二个例子<div id="app"> <v-style> .{{ className }} { background: {{ bgColor }}; position: relative; } .{{ className }}:hover { color: {{ hoverColor }}; } .{{ className }}::after { content: ''; display: block; height: 40px; width: 40px; border: 1px solid black; border-radius: 50%; position: absolute; top: 100%; } </v-style> <div class="temp"> </div> </div> <script> Vue.component('v-style', { render: function (createElement) { return createElement('style', this.$slots.default) } }); export default { data () { return { className: "temp", hoverColor: "yellow", bgColor: "blue" } }, computed () { // 这里和上面一样,所以略去生成 uniqueId 的过程 } } </script>
四、第二个方案——CSS 变量
上面的方案之所以被 Vue 官方不赞成,是因为 Vue 在每次渲染的时候会把每个组件的 style 标签单独拎出来,比较耗费性能。所以有没有一个直观的方案就是 Vue 直接操纵 CSS 呢?,有的,借助 CSS 变量就可以。4.1 快速入门 CSS 变量 ,var() 函数
声明变量的时候,变量名前面要加两根连词线(--)。var()函数还可以使用第二个参数,表示变量的默认值。如果该变量不存在,就会使用这个默认值。
var()函数用于读取变量。
:root 用来定义全局变量
如果是局部变量,则可以在 样式中定义局部变量4.2 快速入门案例
如何定义全局变量和局部变量<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>菜鸟教程(runoob.com)</title> <style> :root { --main-bg-color: coral; --main-txt-color: blue; --main-padding: 15px; } #div1 { background-color: var(--main-bg-color); color: var(--main-txt-color); padding: var(--main-padding); } #div2 { /* 局部定义变量,覆盖默认 root 定义的全局变量 */ --main-bg-color: green; --main-txt-color: red; background-color: var(--main-bg-color); color: var(--main-txt-color); padding: var(--main-padding); } #div3 { /* 定义局部变量 */ --size: 22; background-color: var(--main-bg-color); color: var(--main-txt-color); /* 由于var()后面会默认跟随一个空格,因此在其后面加单位是无效的,比如:--size:20; font-size: var(--size)px会解析成font-size: 20 px; */ padding: calc(var(--size) * 1px); } </style> </head> <body> <h1>var() 函数</h1> <div id="div1">菜鸟教程 - 学的不仅是技术,更是梦想!</div> <br /> <div id="div2">菜鸟教程 - 学的不仅是技术,更是梦想!</div> <br /> <div id="div3">菜鸟教程 - 学的不仅是技术,更是梦想!</div> </body> </html>
如何通过修改样式变量改变样式4.3 Vue 修改CSS变量案例<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>菜鸟教程(runoob.com)</title> <style> :root { --color: green; } .box { --color: yellow; } #box { --color: orange; } * { color: var(--color); } </style> </head> <body> <span>我是绿色,继承根元素</span> <div class="box">我是黄色,通过类设置的</div> <div id="box"> 我是橙色,通过ID设置的(权重最大) <button onclick="changeBg()">改变背景为蓝色</button> </div> </body> <script> function changeBg() { document.getElementById("box").style = "--color: blue;" } </script> </html>
<template> <div class="test"> <span :style="spanStyle" class="span1">hello world</span> <br> <span :style="{'--width': widthVar}" class="span2">hello earth</span> </div> </template> <script> export default { data() { return { spanStyle: { "--color": "red" }, widthVar: "100px" }; } } </script> <style scoped> .span1 { color: var(--color); } .span2 { text-align: center; position: relative; width: var(--width); } .span2::after { content: ''; display: block; position: absolute; left: 100%; width: var(--width); height: var(--width); border-radius: 50%; border: 2px solid black; } </style>
五、总结
第二种方案虽然用起来直观,但不是说第一种方案就一无是处了。第一种方案在用来动态定义全局 CSS 变量的时候很好用。例子如下<component is="style"> :root { --bg-color: {{bgColor}}; --box-size: {{boxSize}}; } </component> <script> export default { data () { return { bgColor: "white", boxSize: "30px" } } } </script>
将二者相辅相成并且结合 Vue 原有的:class和:style,相信大家能写出更优雅的 Vue 代码。