组件组合使用示例
展示多个组件组合使用的实际场景。
搜索表单 + 数据表格
最常见的组合:搜索表单配合数据表格展示。
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>搜索表单 + 表格示例</title>
<link rel="stylesheet" href="./sanoui.min.css">
</head>
<body>
<div style="padding: 20px;">
<!-- 搜索表单 -->
<div style="padding: 16px; background: #f5f7fa; border-radius: 8px; margin-bottom: 16px;">
<div style="display: flex; gap: 10px; flex-wrap: wrap; align-items: center;">
<div class="sa-input"
id="search-input"
data-placeholder="请输入关键词"
data-prefix-icon="search"
style="flex: 1; min-width: 200px; max-width: 300px;">
</div>
<div class="sa-select"
id="status-select"
data-select
data-placeholder="全部状态"
data-options='[{"label":"全部","value":""},{"label":"启用","value":"1"},{"label":"禁用","value":"0"}]'
style="width: 150px;">
</div>
<div class="sa-date-picker"
id="date-picker"
data-date-picker
data-placeholder="选择日期"
style="width: 150px;">
</div>
<button class="sa-button"
id="search-btn"
data-button
data-type="primary"
data-icon="search">
搜索
</button>
<button class="sa-button"
id="reset-btn"
data-button>
重置
</button>
</div>
</div>
<!-- 表格 -->
<div id="data-table" style="height: 400px;"></div>
<!-- 分页 -->
<div id="pagination" style="margin-top: 16px;"></div>
</div>
<script src="./sanoui.min.js"></script>
<script>
// 初始化所有组件
const page = SA.init('body');
// 获取组件实例
const searchInput = page.get('#search-input');
const statusSelect = page.get('#status-select');
const datePicker = page.get('#date-picker');
const searchBtn = page.get('#search-btn');
const resetBtn = page.get('#reset-btn');
// 创建表格
const table = new SaTable('#data-table', {
columns: [
{ prop: 'name', label: '姓名', width: 120 },
{ prop: 'status', label: '状态', width: 100 },
{ prop: 'email', label: '邮箱', width: 200 },
{ prop: 'date', label: '日期', width: 150 }
],
data: []
});
// 创建分页
let currentPage = 1;
const pageSize = 10;
const pagination = new SaPagination('#pagination', {
total: 0,
pageSize: pageSize,
current: currentPage,
layout: 'total, prev, pager, next, jumper',
onChange: (page, size) => {
currentPage = page;
loadData();
}
});
// 加载数据
function loadData() {
const keyword = searchInput ? searchInput.getValue() : '';
const status = statusSelect ? statusSelect.getValue() : '';
const date = datePicker ? datePicker.getValue() : '';
// 模拟数据加载
const data = Array.from({ length: pageSize }, (_, i) => ({
id: (currentPage - 1) * pageSize + i + 1,
name: keyword ? `${keyword}${i + 1}` : `用户${(currentPage - 1) * pageSize + i + 1}`,
status: status || (i % 2 === 0 ? '启用' : '禁用'),
email: `user${(currentPage - 1) * pageSize + i + 1}@example.com`,
date: date || '2024-12-25'
}));
table.setData(data);
pagination.setTotal(100);
}
// 搜索按钮点击
if (searchBtn) {
searchBtn.onClick = () => {
currentPage = 1;
pagination.setCurrent(1);
loadData();
};
}
// 重置按钮点击
if (resetBtn) {
resetBtn.onClick = () => {
if (searchInput) searchInput.setValue('');
if (statusSelect) statusSelect.setValue('');
if (datePicker) datePicker.clear();
currentPage = 1;
pagination.setCurrent(1);
loadData();
};
}
// 初始化加载
loadData();
</script>
</body>
</html>表单 + 对话框
在对话框中嵌入表单的常见场景。
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>表单对话框示例</title>
<link rel="stylesheet" href="./sanoui.min.css">
</head>
<body>
<div style="padding: 20px;">
<button class="sa-button"
id="open-dialog-btn"
data-button
data-type="primary">
打开表单对话框
</button>
</div>
<script src="./sanoui.min.js"></script>
<script>
SA.init('body');
const openBtn = document.getElementById('open-dialog-btn');
openBtn.addEventListener('click', () => {
// 创建对话框内容
const formContent = document.createElement('div');
formContent.innerHTML = `
<form class="sa-form" id="dialog-form" style="padding: 20px;">
<div class="sa-form-item">
<label class="sa-form-item__label">用户名</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="username"
data-placeholder="请输入用户名"
data-clearable="true"></div>
</div>
</div>
<div class="sa-form-item">
<label class="sa-form-item__label">邮箱</label>
<div class="sa-form-item__content">
<div class="sa-input"
data-prop="email"
data-placeholder="请输入邮箱"
data-type="email"></div>
</div>
</div>
</form>
`;
// 创建对话框
const dialog = new SaDialog({
title: '用户信息',
content: formContent,
width: '500px',
onConfirm: () => {
const form = new SaForm('#dialog-form', {
rules: {
username: [{ required: true, message: '请输入用户名' }],
email: [
{ required: true, message: '请输入邮箱' },
{ type: 'email', message: '请输入正确的邮箱格式' }
]
}
});
form.validate().then(valid => {
if (valid) {
const values = form.getValues();
console.log('表单数据:', values);
dialog.close();
}
});
}
});
dialog.open();
// 初始化表单中的组件
setTimeout(() => {
SA.init('#dialog-form');
}, 100);
});
</script>
</body>
</html>表格 + 操作按钮
表格配合操作按钮的组合使用。
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>表格操作示例</title>
<link rel="stylesheet" href="./sanoui.min.css">
</head>
<body>
<div style="padding: 20px;">
<!-- 操作栏 -->
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px;">
<div style="display: flex; gap: 10px;">
<button class="sa-button"
id="add-btn"
data-button
data-type="primary"
data-icon="plus">
新增
</button>
<button class="sa-button"
id="edit-btn"
data-button>
编辑
</button>
<button class="sa-button"
id="delete-btn"
data-button
data-type="danger"
data-icon="delete">
删除
</button>
</div>
<div class="sa-input"
id="search-input"
data-placeholder="搜索..."
data-prefix-icon="search"
style="width: 300px;">
</div>
</div>
<!-- 表格 -->
<div id="operation-table" style="height: 400px;"></div>
</div>
<script src="./sanoui.min.js"></script>
<script>
SA.init('body');
const page = SA.init('body');
const searchInput = page.get('#search-input');
const addBtn = page.get('#add-btn');
const editBtn = page.get('#edit-btn');
const deleteBtn = page.get('#delete-btn');
// 创建表格
const table = new SaTable('#operation-table', {
columns: [
{ prop: 'name', label: '姓名', width: 120 },
{ prop: 'age', label: '年龄', width: 100 },
{ prop: 'email', label: '邮箱', width: 200 },
{
prop: 'actions',
label: '操作',
width: 200,
render: (row) => {
return `
<button class="sa-button sa-button--primary sa-button--small" data-action="edit" data-id="${row.id}">编辑</button>
<button class="sa-button sa-button--danger sa-button--small" data-action="delete" data-id="${row.id}">删除</button>
`;
}
}
],
data: [
{ id: 1, name: '张三', age: 25, email: 'zhangsan@example.com' },
{ id: 2, name: '李四', age: 30, email: 'lisi@example.com' },
{ id: 3, name: '王五', age: 28, email: 'wangwu@example.com' }
]
});
// 新增按钮
if (addBtn) {
addBtn.onClick = () => {
SaDialog.alert({
title: '提示',
content: '打开新增对话框'
});
};
}
// 编辑按钮
if (editBtn) {
editBtn.onClick = () => {
const selectedRows = table.getSelectedRows();
if (selectedRows.length === 0) {
SaMessage.warning('请先选择一行数据');
return;
}
SaDialog.alert({
title: '提示',
content: `编辑: ${selectedRows[0].name}`
});
};
}
// 删除按钮
if (deleteBtn) {
deleteBtn.onClick = () => {
const selectedRows = table.getSelectedRows();
if (selectedRows.length === 0) {
SaMessage.warning('请先选择要删除的数据');
return;
}
SaDialog.confirm({
title: '确认删除',
content: `确定要删除选中的 ${selectedRows.length} 条数据吗?`
}).then(() => {
SaMessage.success('删除成功');
// 执行删除操作
});
};
}
// 搜索
if (searchInput) {
searchInput.onChange = (value) => {
console.log('搜索:', value);
// 执行搜索
};
}
</script>
</body>
</html>表单 + 标签页
使用标签页组织多个表单。
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>表单标签页示例</title>
<link rel="stylesheet" href="./sanoui.min.css">
</head>
<body>
<div style="padding: 20px;">
<div class="sa-tabs" id="form-tabs">
<div class="sa-tabs__header">
<div class="sa-tabs__item sa-tabs__item--active" data-tab="basic">基本信息</div>
<div class="sa-tabs__item" data-tab="detail">详细信息</div>
<div class="sa-tabs__item" data-tab="setting">设置</div>
</div>
<div class="sa-tabs__content">
<!-- 基本信息表单 -->
<div class="sa-tabs__panel" data-tab="basic">
<form class="sa-form" id="basic-form" style="margin-top: 20px;">
<div class="sa-form-item">
<label class="sa-form-item__label">用户名</label>
<div class="sa-form-item__content">
<div class="sa-input" data-prop="username" data-placeholder="请输入用户名"></div>
</div>
</div>
<div class="sa-form-item">
<label class="sa-form-item__label">邮箱</label>
<div class="sa-form-item__content">
<div class="sa-input" data-prop="email" data-type="email" data-placeholder="请输入邮箱"></div>
</div>
</div>
</form>
</div>
<!-- 详细信息表单 -->
<div class="sa-tabs__panel" data-tab="detail" style="display: none;">
<form class="sa-form" id="detail-form" style="margin-top: 20px;">
<div class="sa-form-item">
<label class="sa-form-item__label">地址</label>
<div class="sa-form-item__content">
<div class="sa-input" data-prop="address" data-placeholder="请输入地址"></div>
</div>
</div>
<div class="sa-form-item">
<label class="sa-form-item__label">电话</label>
<div class="sa-form-item__content">
<div class="sa-input" data-prop="phone" data-placeholder="请输入电话"></div>
</div>
</div>
</form>
</div>
<!-- 设置表单 -->
<div class="sa-tabs__panel" data-tab="setting" style="display: none;">
<form class="sa-form" id="setting-form" style="margin-top: 20px;">
<div class="sa-form-item">
<label class="sa-form-item__label">接收通知</label>
<div class="sa-form-item__content">
<div class="sa-switch" data-switch data-checked="true" data-labels='["关闭", "开启"]'></div>
</div>
</div>
<div class="sa-form-item">
<label class="sa-form-item__label">主题</label>
<div class="sa-form-item__content">
<div class="sa-select"
data-select
data-options='[{"label":"浅色","value":"light"},{"label":"深色","value":"dark"}]'
style="width: 200px;">
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<div style="margin-top: 20px;">
<button class="sa-button" data-button data-type="primary">保存</button>
</div>
</div>
<script src="./sanoui.min.js"></script>
<script>
// 初始化所有组件
SA.init('body');
// 标签页切换
const tabItems = document.querySelectorAll('.sa-tabs__item');
const tabPanels = document.querySelectorAll('.sa-tabs__panel');
tabItems.forEach(item => {
item.addEventListener('click', () => {
const tabName = item.getAttribute('data-tab');
// 切换标签
tabItems.forEach(i => i.classList.remove('sa-tabs__item--active'));
item.classList.add('sa-tabs__item--active');
// 切换面板
tabPanels.forEach(p => p.style.display = 'none');
document.querySelector(`.sa-tabs__panel[data-tab="${tabName}"]`).style.display = 'block';
});
});
</script>
</body>
</html>总结
以上示例展示了常见的组件组合使用场景:
- 搜索表单 + 数据表格 - 最常见的后台管理页面模式
- 表单 + 对话框 - 弹窗表单的常见场景
- 表格 + 操作按钮 - 数据列表的操作场景
- 表单 + 标签页 - 复杂表单的组织方式
通过这些组合示例,你可以了解到:
- 如何让多个组件协同工作
- 如何获取和管理组件实例
- 如何处理组件间的事件通信
- 如何组织复杂的页面结构
更多组合使用场景,可以参考实际项目需求进行扩展。