路由组件与一般组件的区别
1. 基本概念
1.1 路由组件
路由组件是指通过路由规则映射的组件,通常放在 pages
或 views
文件夹中。
1.2 一般组件
一般组件是指通过 import
导入后直接使用的组件,通常放在 components
文件夹中。
2. 主要区别
2.1 存放位置
src/
├── pages/ # 路由组件
│ ├── Home/
│ ├── About/
│ └── User/
├── components/ # 一般组件
│ ├── Header/
│ ├── Footer/
│ └── Sidebar/
2.2 接收参数方式
- 路由组件:
javascript
// 路由组件可以接收路由参数
const UserDetail = () => {
// 通过路由获取参数
const { id } = useParams(); // React Router
// 或
const route = useRoute(); // Vue Router
const id = route.params.id;
return <div>User ID: {id}</div>;
};
// 路由配置
const routes = [
{
path: '/user/:id',
component: UserDetail
}
];
- 一般组件:
javascript
// 一般组件通过 props 接收参数
const Button = ({ text, onClick }) => {
return <button onClick={onClick}>{text}</button>;
};
// 使用组件
const App = () => {
return <Button text="Click me" onClick={() => console.log('clicked')} />;
};
2.3 生命周期管理
- 路由组件:
javascript
// React 路由组件
const HomePage = () => {
useEffect(() => {
// 组件挂载时触发
console.log('Route component mounted');
return () => {
// 路由切换时触发卸载
console.log('Route component will unmount');
};
}, []);
return <div>Home Page</div>;
};
// Vue 路由组件
export default {
name: 'HomePage',
beforeRouteEnter(to, from, next) {
// 路由进入前
next();
},
beforeRouteLeave(to, from, next) {
// 路由离开前
next();
}
};
- 一般组件:
javascript
// React 一般组件
const Header = () => {
useEffect(() => {
// 组件挂载时触发
console.log('Normal component mounted');
return () => {
// 父组件更新或条件渲染时可能触发卸载
console.log('Normal component will unmount');
};
}, []);
return <header>Header</header>;
};
// Vue 一般组件
export default {
name: 'Header',
mounted() {
console.log('Normal component mounted');
},
beforeDestroy() {
console.log('Normal component will be destroyed');
}
};
2.4 组件复用性
- 路由组件:
- 通常是页面级组件
- 复用性较低
- 包含业务逻辑
- 可能包含多个一般组件
- 一般组件:
- 通常是功能级组件
- 复用性高
- 专注于特定功能
- 可被多个路由组件使用
3. 实际应用示例
3.1 路由组件示例
javascript
// src/pages/UserList/index.jsx
import { useEffect, useState } from 'react';
import { Table, Button } from '../../components';
const UserList = () => {
const [users, setUsers] = useState([]);
useEffect(() => {
// 获取用户列表数据
fetchUsers();
}, []);
return (
<div className="user-list-page">
<h1>User List</h1>
<Table data={users} />
<Button text="Refresh" onClick={fetchUsers} />
</div>
);
};
export default UserList;
3.2 一般组件示例
javascript
// src/components/Table/index.jsx
const Table = ({ data, columns, onRowClick }) => {
return (
<table className="common-table">
<thead>
<tr>
{columns.map(column => (
<th key={column.key}>{column.title}</th>
))}
</tr>
</thead>
<tbody>
{data.map(row => (
<tr key={row.id} onClick={() => onRowClick(row)}>
{columns.map(column => (
<td key={column.key}>{row[column.key]}</td>
))}
</tr>
))}
</tbody>
</table>
);
};
export default Table;
4. 开发建议
4.1 路由组件开发建议
-
职责划分:
- 负责页面级的状态管理
- 处理路由相关的逻辑
- 组织和协调一般组件
-
代码组织:
javascript
// 推荐的路由组件结构
src/pages/UserManagement/
├── index.jsx // 主组件
├── service.js // API 请求
├── model.js // 数据模型
├── constants.js // 常量定义
└── style.less // 样式文件
4.2 一般组件开发建议
-
设计原则:
- 保持组件的独立性
- 提供良好的 Props 接口
- 避免耦合业务逻辑
-
代码组织:
javascript
// 推荐的一般组件结构
src/components/DataTable/
├── index.jsx // 主组件
├── components/ // 子组件
├── hooks/ // 自定义 hooks
├── utils.js // 工具函数
└── style.less // 样式文件
5. 性能优化
5.1 路由组件优化
javascript
// 路由懒加载
const UserList = React.lazy(() => import('./pages/UserList'));
// 路由配置
const routes = [
{
path: '/users',
component: () => (
<Suspense fallback={<Loading />}>
<UserList />
</Suspense>
)
}
];
5.2 一般组件优化
javascript
// 使用 memo 优化渲染
const Table = React.memo(({ data, columns }) => {
return (
// 表格渲染逻辑
);
});
// 使用 useMemo 优化计算
const List = ({ items }) => {
const sortedItems = useMemo(() => {
return [...items].sort((a, b) => a.id - b.id);
}, [items]);
return (
// 列表渲染逻辑
);
};
6. 总结
6.1 关键区别
-
定位不同:
- 路由组件:页面级,负责整体布局和业务逻辑
- 一般组件:功能级,负责特定功能的实现
-
参数传递:
- 路由组件:主要通过路由参数
- 一般组件:主要通过 props
-
生命周期:
- 路由组件:与路由切换紧密相关
- 一般组件:与父组件更新相关
6.2 使用建议
- 合理划分组件类型
- 遵循单一职责原则
- 注重组件的可复用性
- 保持良好的代码组织结构