20行代码,给你的项目增加 DevUI 主题切换能力

avatar
前端组件库 @华为

Kagol

近期,Vue DevUI 官网上线了主题切换器。

效果如下:

image.png

默认是“充满无限想象”的无限主题:

image.png

可以切换成“满满少女心”的蜜糖主题:

image.png

或者“适合夜猫子”的追光主题:

image.png

本文将手把手教大家如何在自己的项目中引入DevUI的主题切换能力。

1 先要有一个前端项目

如果已经有项目,则可以跳过该步骤。

我们先用vite创建一个Vue3项目,并启动起来:

pnpm create vite my-vue-app -- --template vue-ts
cd my-vue-app/
pnpm i
pnpm dev

为了更好地展示主题切换的效果,我们引入vue-devui组件库。

pnpm i vue-devui

main.ts中增加以下代码:

// 引入vue-devui组件库及其样式文件
import DevUI from 'vue-devui'
import 'vue-devui/style.css'

createApp(App).use(DevUI).mount('#app')

App.vue中加两个按钮:

<d-button variant="solid">确定</d-button>
<d-button>取消</d-button>

效果如下:

image.png

2 加一个主题切换器

主题切换器可以自己制作,这里为了方便演示,所以做得比较简单。

为了简单起见,我们直接使用Radio组件实现主题切换器。

<template>
  <d-radio-group direction="row" v-model="currentTheme">
    <d-radio v-for="item in themeList" :key="item.value" :value="item.value" :name="item.label">
      {{ item.label }}
    </d-radio>
  </d-radio-group>

  <d-button variant="solid">确定</d-button>
  <d-button>取消</d-button>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue'

const currentTheme = ref('infinity-theme');

const themeList = ref([
  {
    value: 'infinity-theme',
    label: '无限'
  },
  {
    value: 'sweet-theme',
    label: '蜜糖'
  },
  {
    value: 'provence-theme',
    label: '紫罗兰'
  },
  {
    value: 'deep-theme',
    label: '深邃夜空'
  },
  {
    value: 'galaxy-theme',
    label: '追光'
  },
]);

watch(currentTheme, (newVal) => {
  // 主题切换的逻辑
  console.log('当前主题:', newVal);
});
</script>

效果如下:

image.png

切换主题时,我们看到控制台打印的主题名称已经发生变化了,当然,由于还没有写主题切换的具体逻辑,所以主题并不会真的切换。

3 引入 devui-theme

要想让主题真的发生切换,就要让本文的主角:devui-theme 出场啦!

devui-themeDevUI提供的一个跨框架跨平台的通用主题定制库,这意味着不管你的项目是基于Vue、React,还是Angular框架的;也不管你的项目是PC端的,还是移动端的,都可以使用。

devui-theme内置5种漂亮的主题,并支持自定义主题。

  • 无限主题infinityTheme(默认)
  • 蜜糖主题sweetTheme
  • 紫罗兰主题provenceTheme
  • 深邃夜空主题deepTheme
  • 追光主题galaxyTheme

先是安装devui-theme

pnpm i devui-theme

在你的项目中使用devui-theme,最关键的就是两步:

  1. 初始化主题 ThemeInit
  2. 切换主题 applyTheme

App.vue中导入ThemeServiceInit和主题对象,并初始化主题。

import {
  ThemeServiceInit,

  // 主题对象
  infinityTheme,
  provenceTheme,
  sweetTheme,
  deepTheme,
  galaxyTheme,
} from 'devui-theme';

// 为了方便根据主题名称获取主题对象,我们定义一个主题映射表
const THEME_MAP = {
  'infinity-theme': infinityTheme,
  'sweet-theme': sweetTheme,
  'provence-theme': provenceTheme,
  'deep-theme': deepTheme,
  'galaxy-theme': galaxyTheme,
};
const currentTheme = ref(localStorage.getItem('user-custom-theme') || THEME_MAP[0]);

// 初始化主题
const themeService = ThemeServiceInit({ ...THEME_MAP }, currentTheme.value);

// 主题切换
watch(currentTheme, (newVal) => {
  // console.log('当前主题:', newVal);
  
  // 调用 applyTheme 方法切换主题
  themeService.applyTheme(THEME_MAP[newVal]);
});

为了展示追光主题的效果,我们需要引入DevUI主题变量:

<style lang="scss">
@import 'devui-theme/styles-var/devui-var';

body {
  background-color: $devui-base-bg;
  color: $devui-text;
}
</style>

使用scss变量前记得安装sass:pnpm i sass

效果如下:

主题切换.gif

参考:

vue-devui.github.io/theme-guide…

贡献者招募

Tree增加虚拟滚动

近期,Tree 组件田主linxiang07同学给Tree组件做了很多优化,修复了一些缺陷,完善了单元测试,最重要的是增加了虚拟滚动,优化了大数据量下的性能👏👏

image.png

Tree 组件采用插件化方式扩展功能,每个功能都是一个独立的 Composable,这在提升可读性和可维护性的同时,也为组件特性的按需引入提供了基础,只有用到了Tree的某个特性,相应的代码才会执行,未执行的代码则会被摇树优化。

Tree组件目前还在持续完善中,欢迎大家一起参与共建!

image.png

DatePickerPro取得突破性进展

另外,DatePickerPro 组件也取得了突破性的进展,daviForevel同学已经完成了 DatePickerPro 最核心的单个日期选择和日期范围选择,后面就是不断增加功能和API啦!

image.png

DatePickerPro是DevUI团队提供的一个开源组件,是为了提供日期选择的效果而精心设计的,算是业界首创。

在设计层面:

  1. 借鉴移动端,利用鼠标滚轮特性及精准点击特性,减少用户操作路径;
  2. 模块化设计,可以按业务需求拆分重组,搭配快速选择区,提升效率。

在用户使用层面:

  1. 组件提供了单选/范围类型,支持日期/周/月份/年份的模式,支持各种自定义模板扩展,充分满足业务复杂场景;
  2. 通过组件封装的方式可以强管控用户的使用方法及样式,同时保证了组件的易用性和一致性;
  3. 参数及使用方式大部分继承了之前的组件,减少了用户的迁移成本。

感兴趣可以参考我们之前写的介绍文章:

DevUI 11.4.0 发布:DatePickerPro来啦 2021.7.13

DatePickerPro 任务认领: github.com/DevCloudFE/…

欢迎加DevUI小助手微信:devui-official,加入我们的技术交流群,一起玩开源!

devui-theme 是框架无关的,大家也可以尝试在其他框架的项目中使用 devui-theme,比如React、Angular项目等

往期文章推荐

Web界面深色模式和主题化开发

DevUI 12.2.0 发布:Dashboard来啦!惊艳!一款超强的布局编排组件!

如何使用 Monaco Editor 做一个在线的网页代码编辑器