Vue's super fun new feature: using JS variables in CSS

Preface

When translating "Vue 3: Mid-2020 Status Update" , it was mentioned in the article that You Yuxi hoped to release the RC version (candidate version) in mid-July and the official version 3.0 in early August.

But it’s already early August, why hasn’t it been released yet? What day is the beginning of this month? So I hurried to go to github to see if there is anything going wrong, and I suddenly found a very interesting feature. I used to think this way: If the variables I defined in data can also be used in CSS That would be great! (Have you ever thought about it this way)

fantasy

When working on projects before, I often thought this way:

<template>
  <h1>{
   
   { color }}</h1>
</template>

<script>
export default {
     
     
  data () {
     
     
  	return {
     
     
  		color: 'red'
  	}
  }
}
</script>

<style>
h1 {
     
     
  color: this.color;
}
</style>

Of course, it is impossible to think about it. JS and CSS belong to different contexts. Where does CSS come from this?

So how can we use JS variables in CSS? Then you can only use JS to manipulate the DOM and stuff the variables into the style, for example, use ref to get the DOM element, and then dom.style.color = this.color.

Or in the template:

<template>
  <h1 :style="{
       
        color }">Vue</h1>
</template>

<script>
export default {
     
     
  data () {
     
     
  	return {
     
     
  		color: 'red'
  	}
  }
}
</script>

However, this method is still flawed. For example, it is not recommended to write styles in the style attribute, and variable reuse will be troublesome. For example, if a group of DOM elements want to use this variable, you have to give this variable. Group a class name, and then document.getElementsByClassName() in mounted. After obtaining the DOM collection, it will loop through each element and add dom.style.color = this.color to it, which wastes a lot of performance.

In fact, CSS itself has many flaws and is not Turing complete, which led to the emergence of various preprocessors: Sass, Less, Stylus, etc...

They provide many features for CSS: loops, conditional statements, variables, functions, etc...

One of the features is very useful, and that is variables ! So CSS also introduced the concept of variables. Since CSS variables have been introduced, many things are really convenient. Manipulating CSS variables through JS and then using CSS variables where needed is much more efficient than before.

What are CSS variables

In JS ( not only JS, all languages ​​are similar ), variables have the following characteristics:

  • statement
  • use
  • Scope

statement

In order to facilitate understanding, let's use JS to make an analogy:

var color = ‘red’;

It is equivalent to:

–color: red;

Of course, this is not the same as JS, but if you learn languages ​​like PHP or Sass, it should be easy to understand. In PHP or Sass, there is no keyword when declaring variables, but the first of the variable name. A dollar sign $ is added to the bit, which means that the variable is declared.

PHP:

$color = 'red';

Sass:

$color: color;

But the $ symbol is occupied by Sass, and the @ symbol is occupied by less, so CSS can only think of other symbols. The CSS symbol is two minus signs –

use

It doesn't make much sense to just declare a variable, and only if you use it, the variable can be considered valuable:

JS:

console.log(color)

You can see that var is just a keyword for declaring variables, and color is the name of the variable.

PHP:

echo $color;

Scss:

h1 {
	color: $color;
}

But in PHP or Sass, when declaring variables with $, you must also carry $ when you use them.

This confuses many developers, so CSS uses a function called var() when using variables :

CSS:

h1 {
    
    
	color: var(--color);
}

Although like PHP and Sass, the call must be prefixed ( because that is part of the variable name ), but the difference is that a var() is needed to wrap the variable.

Scope

This is easy to understand. Not only does JS have scope, but CSS also has scope, such as:

JS:

var color = 'red';

function h1 () {
    
    
	console.log(color);
}

function div () {
    
    
	var color = 'blue';
    console.log(color);
}

h1(); // red
div(); // blue

Similar to CSS:

body {
    
    
	--color: red;
}

h1 {
    
    
	color: var(--color); /** 这里获取到的是全局声明的变量,值为red **/
}

div {
    
    
	--color: blue;
	color: var(--color); /** 这里获取到的是局部声明的变量,值为blue **/
}

In other words, the scope of a variable is the effective scope of the selector in which it is located.

Chinese CSS Variables

Once I saw two libraries with a lot of thoughts, and found that CSS variables can still be played like this:

As you can see from their names, both start with Chinese, so there is a high probability that CSS variables are made in Chinese. Clicking it in is not surprising.

In other words, CSS variables are very inclusive. Unlike in the past when programming, they must be named in English. Chinese can also run perfectly this time. If you don't believe it, let's try it:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <!-- 在这里用link标签引入中文布局 -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/chinese-layout">

  <!-- 在这里用link标签引入中文渐变色 -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/chinese-gradient">
  <style>
    /* 清除默认样式 */
    * {
     
      padding: 0; margin: 0 }
    ul {
     
      list-style: none }

    /* 全屏显示 */
    html, body, ul {
     
      height: 100% }

    /* 在父元素上写入九宫格 */
    ul {
     
     
      display: grid;
      grid: var(--九宫格);
      gap: 5px
    }

    /* 给子元素上色 */
    li {
     
     
      background: var(--极光绿)
    }
  </style>
</head>
<body>
  <ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</body>
</html>

Operation result: In

other words, CSS variables can be defined like this:

body {
    
    
	--蓝绿色: aquamarine;
}

Then when calling:

h1 {
    
    
	color: var(--蓝绿色);
}

Variables in vue

So how can the variables declared in the <script> be used in the <style> of vue3 ?

First, we first create a vite project that supports vue3:

npm init vite app vars

Then enter the folder to install dependencies:

cd vars

above sea level and

Then create a component, the component type looks like this:

<template>
  <h1>{
   
   { color }}</h1>
</template>

<script>
export default {
     
     
  data () {
     
     
    return {
     
     
      color: 'red'
    }
  }
}
</script>

<style vars="{ color }">
h1 {
     
     
  color: var(--color);
}
</style>

Remember what the components in the fantasy I wrote at the beginning of the article are:

<style>
h1 {
     
     
  color: this.color;
}
</style>

However, even if vue is great, it cannot add this to CSS, unless another preprocessor is made, but this time using CSS variables can already be very close to the components in our fantasy:

<style vars="{ color }">
h1 {
     
     
  color: var(--color);
}
</style>

First , write vars="{}" in the <style> tag , and then write the value you declared in data in braces.

Let's try again if this variable is responsive . Will dynamically changing the this.color value in the <script> tag cause the view to change? Try it:

<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 }">
h1 {
     
     
  color: rgb(65, 184, 131);
  opacity: var(--opacity);
}
</style>

Operation result: we

can see that every 300 milliseconds we change the value of this.opacity, it will be mapped to the CSS variable, this.opacity changes, the value of –opacity will change accordingly, and the view will follow the data Update and update accordingly, this feature is simply awesome!

Brains wide open

Since the two CSS libraries chinese-gradient and chinese-layout have verified the feasibility of CSS Chinese variables, and I remember that the properties of objects can also be written in Chinese, let's try to use this black magic in vue To write in Chinese:

<template>
  <h1>Vue</h1>
</template>

<script>
export default {
     
     
  data () {
     
     
    return {
     
     
      '透明度': 0
    }
  },
  mounted () {
     
     
    setInterval(_ => {
     
     
      this['透明度'] >= 1 && (this['透明度'] = 0)
      this['透明度'] += 0.2
    }, 300)
  }
}
</script>

<style vars="{ 透明度 }">
h1 {
     
     
  color: rgb(65, 184, 131);
  opacity: var(--透明度);
}
</style>

operation result:

Home! Of course! tube! use! Up!

In the future, if you don’t know how to name it, don’t use Pinyin, just write Chinese haha! The variable name can be clear at a glance during subsequent maintenance ( but it is still recommended to use English ).

principle

You can also guess, the high probability is that a method similar to dom.style.setProperty('–opacity', this.opacity) is used. Press f12 to open the console and look at it . As expected , it controls the component elements. The style attribute:

But we only used var in the <style> tag just now. Scoped is also very commonly used, so what will it be compiled if they meet together?

<style vars="{ 透明度 }" scoped>
h1 {
     
     
  color: var(--透明度);
}
</style>

Run result:

You can see that Vue has compiled CSS variables to be the same as the random characters after data-v- :

Then the problem is, if I define a –color attribute in the global style , I’m bringing I want to use this global CSS variable in a component with scoped attribute, but once the CSS variable is used in scoped , it will be compiled into: –62a9ebed-color , but the global definition is not –62a9ebed-color but –color , so it will How to solve this problem when the global attribute cannot be found? In fact, very simple, only you need - plus a * behind , Ltd. Free Join: * can be:

<style vars="{ color }" scoped>
h1 {
     
     
  color: var(--global:color);
}
</style>

The compiled CSS will become: var(–color) !

Conclusion

How is it fun? This update of Vue is full of sincerity, but everyone has focused on Composition-API, and did not notice these inconspicuous corners, but these corners can greatly improve our Development experience.

By the way, CSS variables are also compatible: you can see

from the caniuse website that it is not compatible with IE. When using it, remember to confirm the scope of compatibility for your project.

Guess you like

Origin blog.csdn.net/GetIdea/article/details/107767253