React / Vue 前端开发技能。当涉及前端页面开发、React/Vue 组件编写、TypeScript 类型定义、CSS 样式、Vite/Webpack 构建、状态管理时激活。
npm create vite@latest 项目名 -- --template react-ts
cd 项目名
npm install
npm install axios react-router-dom @tanstack/react-query
npm install -D @types/node
npm create vite@latest 项目名 -- --template vue-ts
cd 项目名
npm install
npm install axios vue-router pinia
src/api/request.ts)import axios from 'axios';
const request = axios.create({
baseURL: import.meta.env.VITE_API_BASE || '/api',
timeout: 10000,
});
request.interceptors.request.use((config) => {
const token = localStorage.getItem('token');
if (token) config.headers.Authorization = `Bearer ${token}`;
return config;
});
request.interceptors.response.use(
(res) => {
if (res.data.code !== 200) {
return Promise.reject(new Error(res.data.message));
}
return res.data.data;
},
(err) => Promise.reject(err)
);
export default request;
src/api/xxx.ts)import request from './request';
import type { XxxVO, XxxDTO } from '@/types/xxx';
export const xxxApi = {
list: () => request.get<XxxVO[]>('/xxx'),
getById: (id: number) => request.get<XxxVO>(`/xxx/${id}`),
create: (data: XxxDTO) => request.post<XxxVO>('/xxx', data),
update: (id: number, data: XxxDTO) => request.put<XxxVO>(`/xxx/${id}`, data),
delete: (id: number) => request.delete(`/xxx/${id}`),
};
import { useState, useEffect } from 'react';
interface Props {
title: string;
}
const XxxComponent: React.FC<Props> = ({ title }) => {
const [data, setData] = useState<DataType[]>([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
loadData();
}, []);
const loadData = async () => {
setLoading(true);
try {
const result = await xxxApi.list();
setData(result);
} finally {
setLoading(false);
}
};
return (
<div className="xxx-component">
<h2>{title}</h2>
{loading ? <Spin /> : <DataList data={data} />}
</div>
);
};
<script setup lang="ts">
import { ref, onMounted } from 'vue';
interface Props { title: string }
const props = defineProps<Props>();
const data = ref<DataType[]>([]);
const loading = ref(false);
onMounted(async () => {
loading.value = true;
try { data.value = await xxxApi.list(); }
finally { loading.value = false; }
});
</script>
<template>
<div class="xxx-component">
<h2>{{ props.title }}</h2>
<el-table v-loading="loading" :data="data" />
</div>
</template>
src/types/xxx.ts)// 与后端 API 契约对齐
export interface XxxVO {
id: number;
name: string;
createdAt: string;
}
export interface XxxDTO {
name: string;
}
// 通用分页
export interface PageResult<T> {
total: number;
list: T[];
pageNum: number;
pageSize: number;
}
# 开发
npm run dev
# 构建
npm run build
# 类型检查
npx tsc --noEmit
# 代码检查
npx eslint src/