Vue3新特性之在Composition API中使用CSS Modules


Posted in Javascript onJuly 13, 2020

在 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>

到此这篇关于Vue3新特性之在Composition API中使用CSS Modules的文章就介绍到这了,更多相关Vue3新特性之在Composition API中使用CSS Modules内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
用showModalDialog弹出页面后,提交表单总是弹出一个新窗口
Jul 18 Javascript
jQuery实现获取绑定自定义事件元素的方法
Dec 02 Javascript
bootstrap-wysiwyg结合ajax实现图片上传实时刷新功能
May 27 Javascript
plupload+artdialog实现多平台上传文件
Jul 19 Javascript
AngularJs自定义服务之实现签名和加密
Aug 02 Javascript
AngularJS指令与控制器之间的交互功能示例
Dec 14 Javascript
微信小程序 地图map详解及简单实例
Jan 10 Javascript
jquery获取链接地址和跳转详解(推荐)
Aug 15 jQuery
微信小程序使用progress组件实现显示进度功能【附源码下载】
Dec 12 Javascript
JS 中可以提升幸福度的小技巧(可以识别更多另类写法)
Jul 28 Javascript
JavaScript数组方法的错误使用例子
Sep 13 Javascript
Node使用Selenium进行前端自动化操作的代码实现
Oct 10 Javascript
Threejs实现滴滴官网首页地球动画功能
Jul 13 #Javascript
koa2 数据api中间件设计模型的实现方法
Jul 13 #Javascript
浅析JavaScript 函数防抖和节流
Jul 13 #Javascript
详解JavaScript 异步编程
Jul 13 #Javascript
javascript canvas时钟模拟器
Jul 13 #Javascript
微信小程序整个页面的自动适应布局的实现
Jul 12 #Javascript
uniapp 仿微信的右边下拉选择弹出框的实现代码
Jul 12 #Javascript
You might like
Terran历史背景
2020/03/14 星际争霸
php处理json时中文问题的解决方法
2011/04/12 PHP
PHP 函数call_user_func和call_user_func_array用法详解
2014/03/02 PHP
PHP获取数组最后一个值的2种方法
2015/01/21 PHP
php+mysqli使用预处理技术进行数据库查询的方法
2015/01/28 PHP
织梦sitemap地图实时推送给百度的教程
2015/08/03 PHP
php实现常见图片格式的水印和缩略图制作(面向对象)
2016/06/15 PHP
PHP页面跳转操作实例分析(header方法)
2016/09/28 PHP
golang实现php里的serialize()和unserialize()序列和反序列方法详解
2018/10/30 PHP
csdn 批量接受好友邀请
2009/02/19 Javascript
前端开发部分总结[兼容性、DOM操作、跨域等](持续更新)
2010/03/04 Javascript
js实现俄罗斯方块小游戏分享
2014/01/31 Javascript
基于jQuery的ajax方法封装
2016/07/14 Javascript
一个超简单的jQuery回调函数例子(分享)
2016/08/08 Javascript
jquery 实现复选框的全选操作实例代码
2017/01/24 Javascript
Node.js readline模块与util模块的使用
2018/03/01 Javascript
vue基础之data存储数据及v-for循环用法示例
2019/03/08 Javascript
keep-alive不能缓存多层级路由菜单问题解决
2020/03/10 Javascript
JS遍历树层级关系实现原理解析
2020/08/31 Javascript
vue $mount 和 el的区别说明
2020/09/11 Javascript
Python中encode()方法的使用简介
2015/05/18 Python
Python修改MP3文件的方法
2015/06/15 Python
python3.4用函数操作mysql5.7数据库
2017/06/23 Python
屏蔽Django admin界面添加按钮的操作
2020/03/11 Python
Python语法垃圾回收机制原理解析
2020/03/25 Python
python3代码输出嵌套式对象实例详解
2020/12/03 Python
Pandas DataFrame求差集的示例代码
2020/12/13 Python
英国家喻户晓的折扣商场:TK Maxx
2017/05/26 全球购物
Foreo国际站:Foreo International
2018/10/29 全球购物
庆国庆国旗下讲话稿2014
2014/09/21 职场文书
2014年保险业务员工作总结
2014/12/23 职场文书
优秀共青团员事迹材料
2014/12/25 职场文书
推销搭讪开场白
2015/05/28 职场文书
初中毕业生感言
2015/07/31 职场文书
Mysql中调试存储过程最简单的方法
2021/06/30 MySQL
《现实主义勇者的王国再建记》第三弹OST全曲试听片段公开
2022/04/04 日漫