• 你知道Vue3中style新增了哪些特性吗?


    前言

    Vue3不仅对语法进行了升级,而且还新增了一些style特性,这样在模板中可以更加灵活地使用css样式。下面本篇文章给大家总结分享一下Vue3 style的新特性,希望对大家有所帮助!

    Vue3新增style新特性主要有引入了变量和函数,也就是状态驱动的动态css;插槽选择器;自定义注入名称等,其主要的作用就是使css更加地灵活且模板复用性更强。下面我们就一一地介绍一下每个特性的用法。

    关注公众号:小镇程序猿
    公众号链接

    一、局部样式scoped属性

    当 style 标签带有 scoped 属性的时候,它的 CSS 只会应用到当前组件的元素上,其他组件不会受此样式的影响。

    <style scoped>
      .example {
        color: red;
      }
    </style>
    
    <template>
      <div class="example">hi</div>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    转换为:

    <style>
      .example[data-v-f3f3eg9] {
        color: red;
      }
    </style>
    
    <template>
      <div class="example" data-v-f3f3eg9>hi</div>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在带有 scoped 的时候,父组件的样式将不会泄露到子组件当中。不过,子组件的根节点会同时被父组件的作用域样式和子组件的作用域样式影响。这是有意为之的,这样父组件就可以设置子组件根节点的样式,以达到调整布局的目的。

    二、深度选择器

    在带有 scoped 的时候,它的 CSS 只会应用到当前组件的元素上。因此,就会产生问题,比如,在给

    此处我们以Vant UI组件库的van-button为例,根据自己的样式需求修改该组件的样式,以达到我们的要求,同时其他组件的van-button样式不受此组件影响。具体写法如下:

    <template>
      	<div class="btn">
          <van-button type="primary">按钮</van-button>
        </div>
    </template>
    
    <style lang="scss" scoped>
      .btn {
        :deep(.van-button) {
          background-color: red;
        }
      }
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    提示:通过 v-html 创建的 DOM 内容不会被作用域样式影响,但你仍然可以使用深度选择器来设置其样式。

    标题三、插槽选择器

    默认情况下,作用域的样式不会影响到 渲染出来的内容,因为它们被认为是父组件所持有并传递进来的。使用 :slotted 伪类以确切地将插槽内容作为选择器的目标。

    // 父组件
    <template>
      <div>
        <Child>
          <template #default>
            // p标签的内容显示红色
            <p class="text">我是子组件插槽内容</p>
          </template>
        </Child>
      </div>
    </template>
    <script lang="ts" setup>
    import Child from './child.vue';
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    // 子组件
    <template>
    	<div class="child">
    		<div>我是子组件</div>
    		<slot />
    	</div>
    </template>
    
    <style lang="scss" scoped>
    .child {
    	:slotted(p.text) {
    		color: red;
    	}
    }
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    四、全局选择器

    如果想让其中一个样式规则应用到全局,比起另外创建一个style,可以使用 :global 伪类来实现。看如下代码:

    <style lang="scss" scoped>
      :global(p) {
        color: red;
      }
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    此时,项目中所有组件的 p 标签的字体颜色都会显示红色。

    五、混合使用局部与全局样式

    为了满足不同的代码需求,可以在同一个组件中同时包含作用域样式和非作用域样式。

    <template>
    	<div>
    		
    	</div>
    </template>
    
    <style>
    	/* global styles */
    	/* 对全局组件有效 */
    </style>
    
    <style scoped>
    	/* local styles */
    	/* 样式只对该组件有效 */
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    六、支持style module

    style标签的module属性是很有意思的。

    当我们需要对一个模板遍历多次,并且需要动态地显示css,比如,一个列表根据状态的不同显示不同的css样式,此时,style module 会比 v-bind 绑定 style 样式或者 class 类名来得更方便。

    <template>
    	<div>
    		<p :class="$style.red">我是内容</p>
    	</div>
    </template>
    
    <style lang="scss" module>
    	.red {
    		color: red;
    	}
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    写了 module 就不需要在 style 标签上写 scoped 属性了,因为

    七、自定义注入名称

    我们还可以给style module属性自定义注入类对象的 property 键,也就是给module属行自定义一个名字。

    <template>
    	<div>
    		<p :class="classes.red">我是内容</p>
    	</div>
    </template>
    
    //  给classes自定义一个classes的名字
    <style lang="scss" module="classes">
    	.red {
    		color: red;
    	}
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    八、与组合式 API 一同使用

    注入的类可以通过 useCssModule API 在 setup() 和

    // 默认, 返回