路由表形式react + vite + ts + tailwindcss + pxToRem + axios

打印 上一主题 下一主题

主题 1028|帖子 1028|积分 3084

yarn create vite




在项目当前目录下安装依靠插件:
1、yarn add axios

2、yarn add react

3、 yarn add react-redux

4、 yarn add react-router-dom

5、yarn add redux

6、yarn add reset-css

7、yarn add sass

8、yarn add vite-plugin-svg-icons

9、yarn add postcss-pxtorem

10、目录

 

api/user/index.ts

import { get } from "@/api/http";
export const user = {
  getUserInfo: () => get("/user"),
};
api/http.ts

import http from "@/http";
export interface ApiResult {
  code: number;
  message: string;
  data: any | null | object;
}
export async function get(url: string, params?: any): Promise<ApiResult> {
  const response = await http.get<ApiResult>(url, { params });
  return response?.data;
}
export async function post(url: string, data?: any): Promise<any> {
  const response = await http.post<ApiResult>(url, data);
  return response?.data;
}
export async function put(url: string, data?: any): Promise<any> {
  const response = await http.put<ApiResult>(url, data);
  return response?.data;
}
export async function del(url: string, params?: any): Promise<any> {
  const response = await http.delete<ApiResult>(url, { params });
  return response?.data;
}
api/index.ts

export * from "./user/index";
components/SvgIcon

import { useMemo } from "react";
interface propsInterface {
  name: string;
  size?: string;
  color?: string;
  profix?: string;
}
export default function SvgIcon(props: propsInterface) {
  const size = props.size ?? "24px";
  const color = props.color ?? "";
  const profix = props.profix ?? "icon";
  console.log(color);
  const iconName = useMemo<string>(() => {
    return `#${profix}-${props.name}`;
  }, [profix, props.name]);
  return (
    <svg
      style={{
        height: size,
        width: size,
        fill: color,
        position: "relative",
      }}
      aria-hidden="true"
    >
      <use xlinkHref={iconName} />
    </svg>
  );
}
http/index.ts

import axios from "axios";
const http = axios.create({
  baseURL: "",
  timeout: 5000,
});
// 添加请求拦截器
http.interceptors.request.use(
  function (config) {
    // 在发送请求之前做些什么
    return config;
  },
  function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  }
);
// 添加相应拦截器
http.interceptors.response.use(
  function (response) {
    // 2xx 范围内的状态码都会触发该函数。
    // 对相应数据做点什么
    return response;
  },
  function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对相应错误做点什么
    return Promise.reject(error);
  }
);
export default http;
Layout/Footer.tsx PC端圣杯结构上中下


Layout/Header.tsx


import { useNavigate } from "react-router-dom";
const Header = () => {
  const navigate = useNavigate();
  return (
    <div className="wwj-flex">
      <div className="wwj-cursor-pointer wwj-underline" onClick={() => navigate('/home')}>首页</div>
      <div className="wwj-cursor-pointer wwj-underline wwj-ml-5" onClick={() => navigate('/pageone')}>age1</div>
    </div>
  )
};
export default Header;
Layout/index.tsx

import Header from "./Header"
import Footer from "./Footer"
import Style from './index.module.scss'
import { Outlet } from "react-router-dom"
const Layout = () => (
  <div className={Style.root}>
    <div className="header wwj-w-full wwj-h-[100px] wwj-bg-pink-300">
      <Header />
    </div>
    <div className="main wwj-h-[900px]">
      <Outlet />
    </div>
    <div className="footer wwj-h-[100px] wwj-bg-pink-300">
      <Footer />
    </div>
  </div>
)
export default Layout
Layout/index.module.scss
.root {
  :global {
    width: 100%;
    height: 100vh;
    display: grid;
    grid-template-rows: auto 1fr auto;
    .header {
      position: sticky;
      top: 0;
    }
  }
}
pages/Home/index.tsx
import ViewOne from '@/pages/ViewOne/index'
import SvgIcon from '@/components/SvgIcon/index'
import { useEffect } from 'react';
import { user } from '@/api/index'
const Home = () => {
  useEffect(() => {
    getUserInfo()
  }, [])
  const getUserInfo = () => {
    user.getUserInfo().then(res => {
      console.log(res)
    })
  }
  return (
    <div>
      首页
      <ViewOne />
      <SvgIcon name='age-icon' size='50' color='#c04a4a' />
      <SvgIcon name='react' size='50' color='#c04a4a' />
    </div>
  );
};
export default Home;
pages/PageOne/index.tsx

const PageOne = () => (
  <div>ageOne</div>
)
export default PageOne
pages/ViewOne/index.tsx

const ViewOne = () => (
  <div>
    ViewOne
  </div>
)
export default ViewOne
router/index.tsx

import { lazy } from 'react';
import { useRoutes, RouteObject } from "react-router-dom"
import lazyLoad from './Lazy';
const routes: RouteObject[] = [
  {
    path: '/',
    element: lazyLoad(lazy(() => import('@/Layout/index'))),
    children: [
      {
        path: '/home',
        element: lazyLoad(lazy(() => import('@/pages/Home/index')))
      },
      {
        path: '/pageone',
        element: lazyLoad(lazy(() => import('@/pages/PageOne/index')))
      }
    ]
  }
]
const BaseRouter = () => useRoutes(routes)
export default BaseRouter
router/Layzy.tsx

import { Suspense } from "react";
const lazyLoad = (Com: React.LazyExoticComponent<any>) => {
  return (
    <Suspense>
      <Com />
    </Suspense>
  );
};
export default lazyLoad;
styles/gobal.scss

$color: white;
body {
  // 禁止选中文字
  user-select: none;
  background-color: $color;
}
img {
  // 禁止拖动图片
  -webkit-user-drag: none;
}
styles/tailwind.css
@tailwind base;
@tailwind components;
@tailwind utilities;
utils/pxToRem.ts

// 基准巨细
const baseSize = 16;
// 设置 rem 函数
function setRem() {
  // 当前页面宽度相对于 750 宽的缩放比例,可根据本身需要修改。
  const scale = document.documentElement.clientWidth / 375;
  // 设置页面根节点字体巨细
  document.documentElement.style.fontSize =
    baseSize * Math.min(scale, 2) + "px";
}
// 初始化
setRem();
// 改变窗口巨细时重新设置 rem
window.onresize = function () {
  setRem();
};
App.tsx

import BaseRouter from "./router";
function App() {
  return (
    <BaseRouter />
  )
}
export default App
main.tsx
import ReactDOM from 'react-dom/client'
import App from './App1.tsx'
import 'reset-css'
import '@/styles/global.scss'
import '@/styles/tailwind.css'
import '@/utils/pxToRem.ts'
import 'virtual:svg-icons-register'
import { BrowserRouter } from 'react-router-dom'
ReactDOM.createRoot(document.getElementById('root')!).render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
)
tailwind.config.js

/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {
      screens: {
        sm: '480px',
        md: '768px',
        lg: '976px',
        xl: '1440px',
      },
      spacing: {
        '1': '4px',
        '2': '8px',
        '3': '12px',
        '4': '16px',
        '5': '20px',
        '6': '24px',
      }
    }
  },
  plugins: [],
  prefix: 'wwj-',
}
tsconfig.json

{
  "compilerOptions": {
    "composite": true,
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    "target": "ES2020",
    "useDefineForClassFields": true,
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "skipLibCheck": true,
    /* Bundler mode */
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "moduleDetection": "force",
    "noEmit": true,
    "jsx": "react-jsx",
    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  },
  "include": ["src"]
}
tsconfig.node.json

{
  "compilerOptions": {
    "composite": true,
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
    "skipLibCheck": true,
    "module": "ESNext",
    "moduleResolution": "bundler",
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "noEmit": true
  },
  "include": ["vite.config.ts"]
}
vite.config.ts

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import legacy from "@vitejs/plugin-legacy";
import { resolve } from "path";
import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
import postCssPxToRem from "postcss-pxtorem";
import tailwindcss from "tailwindcss";
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
    legacy({
      targets: ["defaults", "not IE 11"],
    }),
    createSvgIconsPlugin({
      // 指定要缓存的图标文件夹
      iconDirs: [
        resolve(process.cwd(), "src/assets/svg"),
        resolve(process.cwd(), "src/assets/icon"),
      ],
      // 执行icon name的格式
      symbolId: "icon-[name]",
    }),
  ],
  css: {
    postcss: {
      plugins: [
        tailwindcss(),
        postCssPxToRem({
          // 换算基数,
          rootValue: 16,
          propList: ["*"],
        }),
      ],
    },
  },
  server: {
    port: 9999,
    open: true,
    hmr: true,
    proxy: {
      "/user": {
        target: "http://localhost:3999/user",
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/user/, ""),
      },
    },
  },
  resolve: {
    // 设置resole
    alias: {
      "@": resolve(__dirname, "./src"),
    },
  },
});















免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

自由的羽毛

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表