Skip to content

快速开始

使用条件

信息

  • Node.js 16.0.0 及以上版本
  • Vue 3.2.0 及以上版本
  • ElementPlus 2.0.0 及以上版本
  • 在使用 Sunlight-ui 前,要求至少会 Vue3 和 ElementPlus 的基础使用

验证你的环境是否满足以上要求,你可以通过以下命令查看版本:

sh
# 查看 Node.js 版本
node -v

# 查看 Vue 版本(在项目目录下)
npm list vue

# 查看 ElementPlus 版本(在项目目录下)
npm list element-plus

推荐使用如下包管理器安装:

VSCode 插件

推荐使用 VSCode/Cursor 进行开发,以下是推荐的插件:

安装 Sunlight-ui

方法一:通过 npm/yarn/pnpm 安装

在你的 Vue3 项目中执行以下命令安装 Sunlight-ui:

sh
npm install sunlight-ui
sh
yarn add sunlight-ui
sh
pnpm add sunlight-ui

方法二:本地开发安装

如果你需要在本地开发或调试代码,可以克隆仓库并安装:

sh
# 克隆仓库
git clone <sunlight-ui-repository-url>

# 进入目录
cd sunlight-ui

# 安装依赖
pnpm install

# 构建组件库
pnpm build

配置 Sunlight-ui

全局配置

在项目入口文件(通常是 main.tsmain.js)中配置 Sunlight-ui:

ts
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import SunlightUI from 'sunlight-ui'
import 'sunlight-ui/dist/style.css'
import App from './App.vue'

const app = createApp(App)

// 配置 ElementPlus
app.use(ElementPlus)

// 配置 Sunlight-ui
app.use(SunlightUI, {
  // 全局配置项
  table: {
    // 表格组件全局配置
    defaultPageSize: 10, // 默认每页条数
    defaultLayout: 'total, sizes, prev, pager, next, jumper' // 默认分页栏
  },
  input: {
    // 输入框组件全局配置
    defaultClearable: true // 默认显示清空按钮
  }
})

app.mount('#app')

局部配置

在单个组件中使用 Sunlight-ui 组件时,可以通过 props 进行局部配置,局部配置会覆盖全局配置:

vue
<template>
  <div>
    <!-- 表格组件局部配置 -->
    <SunlightTable
      :data="tableData"
      :columns="columns"
      :page-size="20" <!-- 局部配置每页条数,覆盖全局配置 -->
      :layout="'total, prev, pager, next'" <!-- 局部配置分页栏 -->
    />

    <!-- 输入框组件局部配置 -->
    <SunlightInput
      v-model="inputValue"
      :clearable="false" <!-- 局部配置不显示清空按钮,覆盖全局配置 -->
      placeholder="请输入内容"
    />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { SunlightTable, SunlightInput } from 'sunlight-ui'

// 表格数据
const tableData = ref([
  { id: 1, name: '张三', age: 28, status: '启用' },
  { id: 2, name: '李四', age: 32, status: '禁用' }
])

// 表格列配置
const columns = ref([
  { prop: 'id', label: 'ID', width: 80 },
  { prop: 'name', label: '姓名', width: 120 },
  { prop: 'age', label: '年龄', width: 80 },
  { prop: 'status', label: '状态', width: 100 }
])

// 输入框数据
const inputValue = ref('')
</script>

基本使用示例

使用 SunlightTable 组件

vue
<template>
  <div>
    <h3>表格组件示例</h3>
    <SunlightTable
      :data="tableData"
      :columns="columns"
      v-model:hide-columns="hideColumns"
      :show-toolbar="true"
      :show-pagination="true"
    />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { SunlightTable } from 'sunlight-ui'

// 表格数据
const tableData = ref([
  { id: 1, name: '张三', age: 28, status: '启用', email: 'zhangsan@example.com' },
  { id: 2, name: '李四', age: 32, status: '禁用', email: 'lisi@example.com' },
  { id: 3, name: '王五', age: 25, status: '启用', email: 'wangwu@example.com' }
])

// 表格列配置
const columns = ref([
  { prop: 'id', label: 'ID', width: 80 },
  { prop: 'name', label: '姓名', width: 120 },
  { prop: 'age', label: '年龄', width: 80 },
  { prop: 'status', label: '状态', width: 100 },
  { prop: 'email', label: '邮箱' }
])

// 隐藏列配置
const hideColumns = ref(['email']) // 默认隐藏邮箱列
</script>

使用 SunlightInput 组件

vue
<template>
  <div>
    <h3>输入框组件示例</h3>
    <SunlightInput
      v-model="inputValue"
      :clearable="true"
      :placeholder="'请输入内容'"
      @input="handleInput"
      @change="handleChange"
      @focus="handleFocus"
      @blur="handleBlur"
      @clear="handleClear"
      @keydown="handleKeydown"
    />
    
    <div style="margin-top: 20px;">
      <h4>事件触发状态:</h4>
      <ul>
        <li>input 事件:{{ eventStatus.input ? '✓' : '✗' }}</li>
        <li>change 事件:{{ eventStatus.change ? '✓' : '✗' }}</li>
        <li>focus 事件:{{ eventStatus.focus ? '✓' : '✗' }}</li>
        <li>blur 事件:{{ eventStatus.blur ? '✓' : '✗' }}</li>
        <li>clear 事件:{{ eventStatus.clear ? '✓' : '✗' }}</li>
        <li>keydown 事件:{{ eventStatus.keydown ? '✓' : '✗' }}</li>
      </ul>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue'
import { SunlightInput } from 'sunlight-ui'

// 输入框数据
const inputValue = ref('')

// 事件状态
const eventStatus = reactive({
  input: false,
  change: false,
  focus: false,
  blur: false,
  clear: false,
  keydown: false
})

// 事件处理函数
const handleInput = (value: string) => {
  eventStatus.input = true
  setTimeout(() => { eventStatus.input = false }, 500)
}

const handleChange = (value: string) => {
  eventStatus.change = true
  setTimeout(() => { eventStatus.change = false }, 500)
}

const handleFocus = () => {
  eventStatus.focus = true
  setTimeout(() => { eventStatus.focus = false }, 500)
}

const handleBlur = () => {
  eventStatus.blur = true
  setTimeout(() => { eventStatus.blur = false }, 500)
}

const handleClear = () => {
  eventStatus.clear = true
  setTimeout(() => { eventStatus.clear = false }, 500)
}

const handleKeydown = (e: KeyboardEvent) => {
  eventStatus.keydown = true
  setTimeout(() => { eventStatus.keydown = false }, 500)
}
</script>

开发流程

创建新组件

  1. src/components 目录下创建新组件文件夹
  2. 编写组件代码,遵循 Vue3 Composition API 和 TypeScript 规范
  3. src/index.ts 中导出新组件
  4. 编写组件文档和示例

启动开发服务器

sh
# 启动开发服务器
pnpm dev

构建组件库

sh
# 构建组件库
pnpm build

执行测试

sh
# 执行单元测试
pnpm test

# 执行 ESLint 检查
pnpm lint

Sunlight UI 主题管理插件

Sunlight-ui 提供了一个强大的主题管理插件,用于统一设置和管理所有 Sunlight-ui 组件的主题样式。该插件与框架的主题系统无缝集成,实现了主题颜色的全局管理和动态更新。

安装主题管理插件

在使用主题管理插件之前,确保你已经安装了 Sunlight-ui:

sh
npm install sunlight-ui
sh
yarn add sunlight-ui
sh
pnpm add sunlight-ui

配置主题管理插件

1. 创建主题插件文件

在你的项目中创建 src/plugins/sunlightTheme.ts 文件:

ts
import { App } from 'vue'
import { useGlobalStore } from '@/store/modules/global'
import { getLightColor, getDarkColor } from '@/utils/color'

/**
 * Sunlight UI 主题管理插件
 * 用于统一设置 Sunlight-ui 组件的主题样式
 */
export const sunlightThemePlugin = {
  install(app: App) {
    // 初始化主题
    initSunlightTheme()
    
    // 提供全局方法
    app.provide('$sunlightTheme', {
      updateTheme: initSunlightTheme,
      setPrimary: setSunlightPrimary
    })
  }
}

/**
 * 初始化 Sunlight UI 主题
 */
export function initSunlightTheme() {
  const globalStore = useGlobalStore()
  const { primary, isDark } = globalStore
  
  // 设置基础主题颜色
  setSunlightPrimary(primary, isDark)
}

/**
 * 设置 Sunlight UI 主题颜色
 * @param color 主题颜色
 * @param isDark 是否为暗黑模式
 */
export function setSunlightPrimary(color: string, isDark: boolean = false) {
  const html = document.documentElement as HTMLElement
  
  // 计算衍生颜色
  const lightColor = getLightColor(color, 0.2)
  const darkColor = getDarkColor(color, 0.3)
  const hoverColor = isDark ? lightColor : darkColor
  
  // 设置 Sunlight UI 基础变量
  html.style.setProperty('--sunlight-primary', color)
  html.style.setProperty('--sunlight-primary-hover', hoverColor)
  html.style.setProperty('--sunlight-primary-dark', darkColor)
  html.style.setProperty('--sunlight-primary-light', lightColor)
  
  // 设置输入框相关变量
  html.style.setProperty('--sunlight-input-border', isDark ? '#4e5969' : '#c0c4cc')
  html.style.setProperty('--sunlight-input-focus-border', color)
  html.style.setProperty('--sunlight-input-focus-shadow', `0 0 0 3px ${color}20`)
  
  // 设置按钮相关变量
  html.style.setProperty('--sunlight-button-primary-bg', color)
  html.style.setProperty('--sunlight-button-primary-hover', hoverColor)
  
  // 设置选择器相关变量
  html.style.setProperty('--sunlight-select-border', isDark ? '#4e5969' : '#c0c4cc')
  html.style.setProperty('--sunlight-select-focus-border', color)
  
  // 设置文本域相关变量
  html.style.setProperty('--sunlight-textarea-border', isDark ? '#4e5969' : '#c0c4cc')
  html.style.setProperty('--sunlight-textarea-focus-border', color)
}

2. 在主文件中注册插件

main.ts 文件中注册主题管理插件:

ts
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import SunlightUI from 'sunlight-ui'
import 'sunlight-ui/dist/style.css'
import { sunlightThemePlugin } from '@/plugins/sunlightTheme'
import App from './App.vue'

const app = createApp(App)

// 配置 ElementPlus
app.use(ElementPlus)

// 配置 Sunlight-ui
app.use(SunlightUI)

// 配置主题管理插件
app.use(sunlightThemePlugin)

app.mount('#app')

3. 集成到主题系统

useTheme.ts 文件中集成主题管理插件:

ts
import { storeToRefs } from 'pinia'
import { useGlobalStore, defaultPrimary } from '@/store/modules/global'
import { getLightColor, getDarkColor } from '@/utils/color'
import { setSunlightPrimary } from '@/plugins/sunlightTheme'

export const useTheme = () => {
  const globalStore = useGlobalStore()
  const { primary } = storeToRefs(globalStore)

  // 设置主题颜色
  function changePrimary(val: string | null) {
    if (!val) {
      val = defaultPrimary
    }
    const html = document.documentElement as HTMLElement
    // 设置 elementplus 默认主题颜色
    html.style.setProperty('--el-color-primary', val)
    // 设置 elementplus 点击时颜色
    const primaryClickClr = `${getDarkColor(val, 0.3)}`
    document.documentElement.style.setProperty('--el-color-primary-dark-2', primaryClickClr)
    // 设置主题相关高亮颜色
    for (let i = 1; i <= 9; i++) {
      const primaryColor = `${getLightColor(val, i / 10)}`
      document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, primaryColor)
    }
    
    // 同时更新 Sunlight UI 主题颜色
    setSunlightPrimary(val)
    
    globalStore.setGlobalState('primary', val)
  }

  // 初始化主题
  function initTheme() {
    changePrimary(primary.value)
  }

  return { changePrimary, initTheme }
}

使用主题管理插件

1. 基本使用

主题管理插件会自动与框架的主题系统集成,当你通过主题设置面板修改主题颜色时,所有 Sunlight-ui 组件的主题样式会自动更新。

2. 手动更新主题

你可以通过注入的 $sunlightTheme 方法手动更新主题:

vue
<template>
  <button @click="updateTheme">更新主题</button>
</template>

<script setup>
import { inject } from 'vue'

// 注入主题方法
const $sunlightTheme = inject('$sunlightTheme')

// 手动更新主题
function updateTheme() {
  $sunlightTheme.updateTheme()
}
</script>

3. 自定义组件集成

你可以在自定义组件中使用主题变量:

vue
<template>
  <div 
    class="custom-component"
    :style="{
      borderColor: 'var(--sunlight-input-border)',
      color: 'var(--sunlight-primary)'
    }"
  >
    自定义组件
  </div>
</template>

主题管理插件的优势

  1. 统一管理:集中控制所有 Sunlight-ui 组件的主题样式
  2. 无缝集成:与现有主题系统完全兼容
  3. 动态更新:主题颜色变化时自动更新所有组件
  4. 向后兼容:保留组件原有的自定义样式能力
  5. 衍生颜色:自动计算主题的衍生颜色,确保视觉一致性

常见问题

1. 为什么组件样式不生效?

请确保你已经正确导入了样式文件:

ts
import 'sunlight-ui/dist/style.css'

2. 为什么全局配置不生效?

请确保在使用组件之前配置 Sunlight-ui:

ts
// 先配置
app.use(SunlightUI, {
  // 配置项
})

// 再挂载应用
app.mount('#app')

3. 如何自定义组件样式?

你可以通过以下方式自定义组件样式:

  1. 使用 CSS 选择器覆盖样式
  2. 使用 ElementPlus 的主题定制功能
  3. 通过组件的 classstyle 属性自定义
  4. 使用 Sunlight UI 主题管理插件

更多使用请参考各组件的详细文档。