# `@deppon/deppon-template`

业务组件库（Vue 3）

## 安装

```bash
npm install @deppon/deppon-template
```

## 配置

由于组件库使用 Less 编写样式，你需要在项目中配置 Less 支持。

> 📖 **详细使用指南：**
>
> -   [Vite 项目使用指南](./VITE_USAGE.md) - 完整的 Vite + Vue 3 使用示例
> -   [通用使用示例](./USAGE.md) - 包含常见问题和解决方案

### Vite 项目

Vite 默认支持 Less，无需额外配置。如果遇到问题，确保已安装 `less`：

```bash
npm install -D less
```

**快速开始：**

```vue
<template>
    <ProLayout :menu-items="menuItems" :active-menu="activeMenu" title="我的应用">
        <router-view />
    </ProLayout>
</template>

<script setup>
import { ref } from 'vue';
import { ProLayout } from '@deppon/deppon-template';
// ✅ Less 文件会自动导入并编译

const activeMenu = ref('/home');
const menuItems = ref([
    { path: '/home', title: '首页' },
    { path: '/about', title: '关于' },
]);
</script>
```

查看 [VITE_USAGE.md](./VITE_USAGE.md) 获取完整示例。

### Webpack 项目

需要安装并配置 Less 加载器：

```bash
npm install -D less less-loader
```

在 `webpack.config.js` 或 `vue.config.js` 中配置：

```javascript
module.exports = {
    module: {
        rules: [
            {
                test: /\.less$/,
                use: ['style-loader', 'css-loader', 'less-loader'],
            },
        ],
    },
};
```

## 使用

### 完整引入

```vue
<template>
    <ProLayout :menu-items="menuItems" :active-menu="activeMenu" title="我的应用">
        <router-view />
    </ProLayout>
</template>

<script setup>
import { ProLayout } from '@deppon/deppon-template';
// 样式会自动导入（Less 文件会被自动处理）

const menuItems = [
    {
        path: '/home',
        title: '首页',
        icon: HomeFilled,
    },
    {
        path: '/about',
        title: '关于',
        icon: Document,
    },
];

const activeMenu = '/home';
</script>
```

### 按需引入

```vue
<template>
    <div>
        <ProLayout :menu-items="menuItems" />
        <ProForm :form-items="formItems" />
        <ProTable :columns="columns" :data="tableData" />
    </div>
</template>

<script setup>
// 按需导入组件，样式会自动导入
import { ProLayout, ProForm, ProTable } from '@deppon/deppon-template';

const menuItems = [];
const formItems = [];
const columns = [];
const tableData = [];
</script>
```

### 单独导入组件

```vue
<template>
    <ProLayout :menu-items="menuItems" />
</template>

<script setup>
// 从子路径导入，样式会自动导入
import ProLayout from '@deppon/deppon-template/pro-layout';
// 或者
import { ProLayout } from '@deppon/deppon-template';
</script>
```

### 样式说明

-   **自动导入**：当你导入组件时，对应的 Less 文件会自动被导入
-   **Less 编译**：Less 文件会被你的构建工具（Vite/Webpack）自动编译为 CSS
-   **:deep() 支持**：Less 文件中的 `:deep()` 语法会被正确处理
-   **无需手动导入样式**：不需要手动 `import '@deppon/deppon-template/es/pro-layout/ProLayout.vue.less'`

### 完整示例（Vite + Vue 3）

```vue
<!-- App.vue -->
<template>
    <ProLayout
        :menu-items="menuItems"
        :active-menu="activeMenu"
        title="管理系统"
        :show-logo="true"
        :show-header="true"
        :fixed-header="true"
        @collapse-change="handleCollapseChange"
    >
        <template #header-right>
            <el-button>用户中心</el-button>
        </template>

        <router-view />
    </ProLayout>
</template>

<script setup>
import { ref } from 'vue';
import { ProLayout } from '@deppon/deppon-template';
import { HomeFilled, Document, Setting } from '@deppon/deppon-ui/icons-vue';

const activeMenu = ref('/home');
const collapsed = ref(false);

const menuItems = ref([
    {
        path: '/home',
        title: '首页',
        icon: HomeFilled,
    },
    {
        path: '/documents',
        title: '文档',
        icon: Document,
        children: [
            {
                path: '/documents/list',
                title: '文档列表',
            },
        ],
    },
    {
        path: '/settings',
        title: '设置',
        icon: Setting,
    },
]);

const handleCollapseChange = val => {
    console.log('侧边栏折叠状态:', val);
};
</script>
```

### 完整示例（Webpack + Vue 3）

```vue
<!-- App.vue -->
<template>
    <ProLayout :menu-items="menuItems" :active-menu="activeMenu">
        <router-view />
    </ProLayout>
</template>

<script>
import { ref } from 'vue';
import { ProLayout } from '@deppon/deppon-template';

export default {
    name: 'App',
    components: {
        ProLayout,
    },
    setup() {
        const activeMenu = ref('/home');
        const menuItems = ref([
            { path: '/home', title: '首页' },
            { path: '/about', title: '关于' },
        ]);

        return {
            activeMenu,
            menuItems,
        };
    },
};
</script>
```

## 使用

### useScrollEnd Composable

监听滚动到底部的事件。

```vue
<template>
    <div class="scroll-container" ref="scrollContainer">
        <!-- 内容 -->
    </div>
</template>

<script setup>
import { ref } from 'vue';
import { useScrollEnd } from '@deppon/deppon-template';

const scrollContainer = ref(null);

// 监听滚动到底部
useScrollEnd(
    () => {
        console.log('滚动到底部了');
        // 加载更多数据
        loadMore();
    },
    50, // 距离底部的阈值（像素）
    '.scroll-container', // 滚动容器的选择器，可选
);

const loadMore = () => {
    // 加载更多逻辑
};
</script>
```

#### 参数

| 参数                  | 说明                       | 类型       | 默认值                                   |
| --------------------- | -------------------------- | ---------- | ---------------------------------------- |
| callback              | 滚动到底部时触发的回调函数 | `function` | 必填                                     |
| thresholds            | 距离底部的阈值（像素）     | `number`   | `0`                                      |
| scrollElementSelector | 滚动容器的选择器           | `string`   | `null`（使用 document.scrollingElement） |

### Events

事件总线，用于组件间通信。基于 [mitt](https://github.com/developit/mitt) 实现，轻量级且专为浏览器设计。

```vue
<script setup>
import { events } from '@deppon/deppon-template';

// 监听事件
events.on('some-event', data => {
    console.log('收到事件:', data);
});

// 触发事件
events.emit('some-event', { key: 'value' });

// 移除监听
events.off('some-event');
</script>
```

### Track

埋点工具函数。

```vue
<script setup>
import { gt } from '@deppon/deppon-template';

// 使用埋点
const handleClick = () => {
    const trackData = gt('gbdetail_buy_nk_pv');
    // trackData 包含埋点所需的数据
    console.log(trackData);
};
</script>
```

## 设计规范

-   [设计规范文档（Markdown）](./docs/design-spec.md)
-   [设计规范可视化页面](./docs/design-spec.html)（浏览器直接打开）

## ProIframe 内嵌页

在 ProLayout 内通过 iframe 加载页面，支持路由动态传 `url`。详见 [docs/pro-iframe.md](./docs/pro-iframe.md) 或文档站 [ProIframe 说明](../../docs/docs/deppon-template-pro-iframe.md)。

## License

MIT
