专栏首页云前端Vue 3 新特性:在 Composition API 中使用 CSS Modules

Vue 3 新特性:在 Composition API 中使用 CSS Modules

在 Vue 3 Composition API 最近的一次 beta 升级中,无论是 Vue 3 本 3 库 vue-next,还是面向 Vue 2 过渡用的 @vue/composition-api 库中,都同步更新了一个 useCSSModule 函数 -- 用来在使用了 Composition API 的 Vue 实例中,支持 CSS Modules 语法。

首先来看看什么是 CSS Modules:

CSS Modules

CSS Modules 是一种 CSS 的模块化和组合系统。vue-loader 集成 CSS Modules,可以作为模拟 scoped CSS 的替代方案。

启用 CSS Modules

如果是使用 vue cli 创建的项目,应该已经默认开启了这一特性;如果项目中需要手动开启,按如下设置:

// webpack.config.js
{
  module: {
    rules: [
      // ... 其它规则省略
      {
        test: /\.css$/,
        use: [
          'vue-style-loader',
          {
            loader: 'css-loader',
            options: {
              // 开启 CSS Modules
              modules: true,
              // 自定义生成的类名
              localIdentName: '[local]_[hash:base64:8]'
            }
          }
        ]
      }
    ]
  }
}

或者与其它预处理器一起使用:

// webpack.config.js -> module.rules
{
  test: /\.scss$/,
  use: [
    'vue-style-loader',
    {
      loader: 'css-loader',
      options: { modules: true }
    },
    'sass-loader'
  ]
}

然后在组件中的 <style> 上添加 module 特性:

<style module>
.red {
  color: red;
}
.bold {
  font-weight: bold;
}
</style>

在组件中访问 CSS Modules

<style> 上添加 module 后,一个叫做 $style 的计算属性就会被自动注入组件。

<template>
  <div>
    <p :class="$style.red">
      hello red!
    </p>
  </div>
</template>

因为这是一个计算属性,所以也支持 :class 的对象/数组语法:

<template>
  <div>
    <p :class="{ [$style.red]: isRed }">
      Am I red?
    </p>
    <p :class="[$style.red, $style.bold]">
      Red and bold
    </p>
  </div>
</template>

也可以通过 JavaScript 访问:

<script>
export default {
  created () {
    console.log(this.$style.red)
  }
}
</script>

Vue 2.x 传统用法

在 Options API 组件中:

<template>
  <span :class="$style.span1">hello 111 - {{ text }}</span>
</template>

<script>
export default {
  props: {
    text: {
      type: String,
      default: ''
    }
  }
};
</script>

<style lang="scss" module>
.span1 {
  color: red;
  font-size: 50px;
}
</style>

对于 JSX 组件,由于其没办法用 scoped style,所以 CSS Modules 是个很好的选择:

<script>
export default {
  props: {
    text: {
      type: String,
      default: ''
    }
  },
  render(h) {
    return <span class={this.$style.span1}>hello 222 - {this.text}</span>;
  }
};
</script>

<style lang="scss" module>
.span1 {
  color: blue;
  font-size: 40px;
}
</style>

Vue 3.x 中的 useCSSModule

引入 useCSSModule 函数后,在 Composition API 组件中使用 CSS Modules 就有了标准方案:

<template>
  <span :class="$style.span1">hello 333 - {{ text }}</span>
</template>

<script>
import { useCSSModule } from '@vue/composition-api';

export default {
  props: {
    text: {
      type: String,
      default: ''
    }
  },
  setup(props, context) {
    const $style = useCSSModule();
    return {
      $style
    };
  }
};
</script>

<style lang="scss" module>
.span1 {
  color: green;
  font-size: 30px;
}
</style>

其源码实现也是非常之简单,基本就是取出 this.$style 而已:

export const useCSSModule = (name = '$style'): Record<string, string> => {
  const instance = getCurrentInstance()
  if (!instance) {
    __DEV__ && warn(`useCSSModule must be called inside setup()`)
    return EMPTY_OBJ
  }

  const mod = (instance as any)[name]
  if (!mod) {
    __DEV__ &&
      warn(`Current instance does not have CSS module named "${name}".`)
    return EMPTY_OBJ
  }

  return mod as Record<string, string>
}

自定义 CSS Modules 注入名称

通过观察 useCSSModule 的源码发现,CSS Modules 的 name 好像可以不只是 $style;确实,在 .vue 文件中可以定义不止一个 <style module>,这可以通过设置 module 特性的值实现:

<style module="a">
  /* 注入标识符 a */
</style>

<style module="b">
  /* 注入标识符 b */
</style>

--End--

本文分享自微信公众号 - 云前端(fewelife),作者:云前端

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-07-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 实用!最新的几个 Vue 3 重要特性提案

    在几天前开启的 SFC Improvements #182 中,yyx990803 提交了 3 个改进开发者体验的征求意见稿。

    江米小枣
  • 手把手带你用 Vue 3.0 写个小程序框架

    由于小程序的开发起来比较原始复杂且繁琐,跟我们主流的开发方式差距很大,所以为了提高我们开发小程序的效率,市面上出现过很多的小程序的框架:mpvue,Taro,u...

    极乐君
  • Taro 支持使用 Vue3 开发小程序

    9 月 19 日凌晨,Vue3 在经过多个开发版本的迭代后,终于迎来了它的正式版本,"One Piece" 的代号也昭示了其开拓伟大航路的野心。

    一只图雀
  • [译] 用 Typescript + Composition API 重构 Vue 3 组件

    原文:https://vuejs-course.com/blog/vuejs-3-typescript-options-composition-api

    江米小枣
  • 《vue3+ts+element-plus 后台管理系统系列》之vuex4.x

    Vuex4.x 和 TS 一起分包变化也是比较多的,先从官方例子说起。基础例子请查看官网,传送vuex4.x官网。

    ZY_FlyWay
  • 还学的动吗? 盘点下Vue.js 3.0.0 那些让人激动的功能

    路漫漫其修远兮,吾将上下而求索。——献给所有为 Vue的发展而默默付出的开发者们。

    葡萄城控件
  • 拥抱 Vite2.0 系列(二)

    在最基本的层次上,使用Vite进行开发与使用静态文件服务器没有太大区别。但是,Vite对本机ESM导入提供了许多增强功能,以支持通常在基于捆绑程序的设置中常见的...

    公众号---人生代码
  • Vuejs 3.0 正式版发布!One Piece. 代号:海贼王

    Vue 团队于 2020 年 9 月 18 日晚 11 点半发布了 Vue 3.0 版本。

    夜尽天明
  • Vue 3.0 中令人激动的新功能:Portals+新的自定义指令API

    第二篇:Vue 3.0 中令人激动的新功能:Fragment+Suspense+多个v-model

    前端开发博客
  • Vue 3.0 源码分析-数据侦测

    2020年前端大事件之一,Vue 3.0终于正式发布了。作为一个大的版本更新,Vue 3 与 Vue 2相比,实现原理,使用方式等均有着不小的改动。本文主要会...

    QQ音乐前端团队
  • Vue3.0入门 + Vant3.0移动端实践(二)轮播图模块封装及首页完善

    接着上一篇的来,上一篇介绍了环境搭建及做好了底部的导航栏模块,接下来继续完善首页。

    独行猫A
  • [译] Vue 3 Composition API 之单元测试

    原文:https://itnext.io/testing-the-composition-api-fae3bae3f592

    江米小枣
  • Vue3 Composition API教程及示例

    Vue引入了Composition API(基于功能的API)作为当前基于Option的API的补充。该API将随Vue 3一起发布,但是现在您可以通过将Vue...

    前端知否
  • Vue 3中令人激动的新功能:Composition API

    在上一篇文章中,我们了解了Vue 3将带来的性能提升。我们已经知道在Vue新的主要版本中编写的应用程序会有很好的性能,但性能并不是最重要的部分。对我们开发者来说...

    前端开发博客
  • 译文:Vue3 Composition API 是如何取代 Vue Mixins 的?

    原文:https://css-tricks.com/how-the-Vue-composition-api-replaces-vue-mixins/

    前端开发博客
  • 使用Vue3.0,我收获了哪些知识点(一)

    近期工作感觉很忙,都没有多少时间去写文章,今天这篇文章主要是将自己前期学习Vue3.0时候整理的一些笔记内容进行了汇总,通过对本文的阅读,你将可以自己完成Vue...

    用户1308196
  • [译] 对比 React Hooks 和 Vue Composition API

    原文:https://dev.to/voluntadpear/comparing-react-hooks-with-vue-composition-api-4b...

    江米小枣
  • Vue3 + TypeScript 开发实践总结

    迟来的Vue3文章,其实早在今年3月份时就把Vue3过了一遍。 在去年年末又把 TypeScript 重新学了一遍,为了上Vue3 的车,更好的开车。 在上家公...

    小阿新
  • 第 001 期 聚集零散业务代码的解决方案 - Vue 3 Composition API

    用 Vue 时,常出现相关业务逻辑代码散在 data, methods, watch, computed 和 mounted 等地方。这样的代码可维护性差。查找...

    前端GoGoGo

扫码关注云+社区

领取腾讯云代金券