• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

第三章 使用UnoCSS原子化CSS

武飞扬头像
天界程序员
帮助1

第三章 使用UnoCSS原子化CSS

原子样式也有很多选择,最著名的就是 TailwindTailwind 虽然好,但是性能上有一些不足。由于Tailwind 会生成大量样式定义。全量的 CSS 文件往往体积会多至数 MB。这个对于页面性能是完全不可接受的。如果在开发时进行动态的按需剪裁,又会影响编译性能,降低开发体验。为了解决性能问题,开源界一个叫做 Antfu 的大神设计了 UnoCSSUnoCSS 是一个拥有高性能且具灵活性的即时原子化 CSS 引擎,可以兼顾产物体积和开发性能。

本章任务

  • 引入 UnoCSS 样式

  • 实现组件属性定制按钮样式

  • 实现【Icon图标按钮】

task1】引入UnoCSS样式

  • 安装依赖
pnpm i -D unocss@"0.45.6"
pnpm i -D @iconify-json/ic@"1.1.4" 

其中的@iconify-json/ic 是字体图标库

  • 在Vite配置文件中添加UnoCSS插件

文件名:vite.config.ts

import { presetUno, presetAttributify, presetIcons } from "unocss";
import Unocss from "unocss/vite";
export default defineConfig({
  plugins: [
    ...
    // 添加UnoCSS插件
    Unocss({
        presets: [presetUno(), presetAttributify(), presetIcons()],
    })
  ],
});

下面就可以在插件中引入 UnoCSS 了。加载 Unocss 插件后,Vite 会通过分析 class 的使用状况提供相应的样式定义。

  • Button 组件中引入 UnoCSS

文件名:src/button/index.tsx

注意: 这个地方文件名已经从 index.ts变为 index.tsx

import { defineComponent,PropType,toRefs} from "vue";
import "uno.css";
export default defineComponent({
  name: "SButton",
  setup(props, {slots}) {
    return () => <button 
      class={`
      py-2 
      px-4 
      font-semibold 
      rounded-lg 
      shadow-md 
      text-white 
      bg-green-500 
      hover:bg-green-700 
      border-none 
      cursor-pointer 
      `}
        > 
        {slots.default ? slots.default() : ''}
     </button>
  }
});
  • index.ts 中添加一个测试代码

文件名: src/index.ts

import { createApp } from "vue";
import SmartyUI from "./entry"

createApp({
  template:`
      <div>
          <SButton>普通按钮</SButton>
      </div>
  `
})
.use(SmartyUI)
.mount("#app");
  • 启动项目
pnpm dev
  • 在浏览器输入地址查看按钮组件
  VITE v3.0.7  ready in 644 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose

此时并没有看见页面出现按钮组件,且浏览器控制台抛出警告:

runtime-core.esm-bundler.js:38 [Vue warn]: Component provided template option but runtime compilation is not supported in this build of Vue. Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js". 
  at <App>

这个警告的意思是:组件提供 template 选项,但是在Vue的这个构建中不支持运行时编译,在你的打包工具里配置别名“vue: vue/dist/vue.esm-bundler.js”

  • 分析原因

项目的 vue/dist 目录下有很多不同的 Vue.js 构建版本,不同的环境使用不同的构建版本。使用构建工具的情况下,默认使用的是 vue.runtime.esm-bundler.js 这个仅运行时版本,不能处理 template 选项是字符串的情况,template 选项是字符串的情况要使用包含运行时编译器的版本 vue.esm-bundler.js

  • 解决方案

在vite配置文件中配置别名resolve

文件名:vite.config.ts

export default defineConfig({
  resolve: {
    alias: {
      vue: 'vue/dist/vue.esm-bundler.js',
    },
  },
  plugins: [
        ...
        // 插件
  ]
 })

修改好别名后,保存就可以在浏览器看见一个绿色按钮了。

到此为止,说明 UnoCSS 已经正常引入了。


task2】实现组件属性定制按钮样式

根据属性定制按钮样式功能,就是可以修改组件的属性来达到你想要的目的,例如,通过color属性定制颜色。

 <div>
  <SButton color="blue">蓝色按钮</SButton>
  <SButton color="green">绿色按钮</SButton>
  <SButton color="gray">灰色按钮</SButton>
  <SButton color="yellow">黄色按钮</SButton>
  <SButton color="red">红色按钮</SButton>
 </div>
  • 定义属性类型并注册组件属性

文件名:src/button/index.tsx

import { defineComponent,PropType,toRefs} from "vue";
import "uno.css";

// 颜色类型声明
export type IColor = 'black' | 'gray' | 'red' | 'yellow' | 'green'|'blue'|'indigo'|'purple'|'pink'

export const props = {
  color: {
    type: String as PropType<IColor>,
    default: 'blue'  // 设定默认颜色
  },
}
export default defineComponent({
  name: "SButton",
  props,  // 注册属性
  ...
  }
});
  • 属性变量拼装 UnoCSS

文件名:src/button/index.tsx

export default defineComponent({
  name: "SButton",
  props,
  setup(props, {slots}) {
    return () => <button 
        class={`
          py-2 
          px-4 
          font-semibold 
          rounded-lg 
          shadow-md 
          text-white 
          bg-${props.color}-500 
          hover:bg-${props.color}-700 
          border-none 
          cursor-pointer 
          m-1
          `}
        > 
        {slots.default ? slots.default() : ''}
     </button>
  }
});
  • 修改index.ts文件,添加测试用例

文件名:src/index.ts

import { createApp } from "vue";
import SmartyUI from './entry'

createApp({
  template:`
  <div>
    <SButton color="blue">蓝色按钮</SButton>
    <SButton color="green">绿色按钮</SButton>
    <SButton color="gray">灰色按钮</SButton>
    <SButton color="yellow">黄色按钮</SButton>
    <SButton color="red">红色按钮</SButton>
 </div>
  `
})
.use(SmartyUI)
.mount("#app");
  • 启动项目
pnpm dev
  • 在浏览器页面中查看

可以看到组件,但是但是灰色的,并没有看到我们给组件属性配置的颜色。这是为什么?

仔细研究 UnoCSS 的文档才发现问题。主要原因是 UnoCSS 默认是按需生成方式。也就是说只生成代码中使用过的样式。那如果在 class 属性中使用变量,是无法分析变量的取值的。这样也就无法动态生成样式了。

为了解决这个问题,UnoCSS 提供了安全列表选项。也就是说,把样式定义中变量的取值添加到 Safelist 中去。这样 UnoCSS 就会根据 Safelist 生成样式了。

  • 开始定制安全列表

安全列表属性应该定义在 UnoCSS 插件的配置中。

这里面要做一个配置上的重构。考虑到后续会在 Safelist 中添加大量配置,所以我们将 UnoCSS 配置拆成一个新的 ts 模块,然后引用到 vite.config.ts 中。

项目在搭建的过程中会不断地进行重构。希望大家在开发的过程中,一定要积极思考如何编写更加合理易于维护的代码。

文件名:config/unocss.ts

import { presetUno, presetAttributify, presetIcons } from "unocss";
import Unocss from "unocss/vite";

const colors = [
  "white",
  "black",
  "gray",
  "red",
  "yellow",
  "green",
  "blue",
  "indigo",
  "purple",
  "pink",
];

const safelist = [

  ...colors.map((v) => `bg-${v}-500`),
  ...colors.map((v) => `hover:bg-${v}-700`),
];

export default () =>
  Unocss({
    safelist,
    presets: [presetUno(), presetAttributify(), presetIcons()],
  });
  • vite配置中引入重构的unocss配置

文件名:vite.config.ts

import Unocss from "./config/unocss";

export default defineConfig({

  plugins: [
	// 重构后的unocss配置
    Unocss(),
  ],

})
  • 重启项目
pnpm dev
  • 在浏览器查看结果

此时可以看到组件,以及我们想要的对应的组件属性所配置的颜色了。


task3】Icon 图标按钮实现

接下来要给按钮增加图标定制功能。实现图标按钮,首先需要引入字体图标库。

UnoCSS 中引入图标,只需要加载 @unocss/preset-icons 预设就可以了。它提供了 iconify 图标框架中大量的图表集。

iconfy官方网站

  • 开始引入这个功能,首先在 Unocss 插件中添加 presetIcons 预设。

文件名: config/unocss.ts

export default () =>
  Unocss({
    safelist,
    presets: [
        presetUno(),   
        presetAttributify(), 
        presetIcons(),  // 添加图标预设
    ]
  });
  • 定制图标安全列表

为了能够在 UnoCSS 中使用变量定义字体图标,需要将使用的图标名加入到 safelist 中。

文件名:config/unocss.ts

const safelist = [
  ...[
    "search",
    "edit",
    "check",
    "message",
    "star-off",
    "delete",
    "add",
    "share",
  ].map((v) => `i-ic-baseline-${v}`),
];
  • Button组件中注册icon属性

文件名:src/button/index.tsx

export const props = {
  icon: { // 注册icon属性
    type: String,
    default: ''
  }
}
  • Button组件 中添加字体图标

文件名:src/button/index.tsx

return () => <button 
        class={`
            ...
          mx-1
          `}
        > 
        { props.icon !== "" ? <i class={`i-ic-baseline-${props.icon} p-3`}></i> : ""}
        {slots.default ? slots.default() : ''}
 </button>
  • index.ts中添加测试用例

文件名:src/index.ts

import { createApp } from 'vue'
import SmartyUI from './entry'

createApp({
  template: `
 <div style="margin-top:20px;">
    <SButton color="blue"   icon="search" ></SButton>
    <SButton color="green" icon="edit"></SButton>
    <SButton color="gray"  icon="check"></SButton>
    <SButton color="yellow"  icon="message"></SButton>
    <SButton color="red"  icon="delete"></SButton>
  </div>
  `,

本篇文章来至:学新通

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通
  • 本文地址: https://www.swvq.com/boutique/detail/tanhcikcji
  • 联系方式: luke.wu#vfv.cc
系列文章
更多 icon
同类精品
更多 icon
我要评论
我的头像
精彩评论
继续加载