从0到1搭建一个项目(基于Vue3 Vite4手搭)

大家根据个人习惯选择安装这些依赖。

  • vue:经常使用的框架
  • axios:vue官方推荐http请求库
  • pinia:vue官方推荐状态管理工具
  • pinia-plugin-persistedstate:pinia数据持久化插件
  • vue-router:路由管理工具
  • typescript:使用TS语言
  • less:css预处理
  • element-plus:常见组件库

 1.搭建一个基础的Vue项目结构


    |- public        # 不经过打包的静态资源
    |- src           # 项目资源
        |- assets        # 经过打包的静态资源
        |- components    # 通用组件
        |- styles        # 项目通用样式
            |-  reset.less      # 重置样式
        |- http        #  axios封装函数
            |- requtest.ts     # axios封装
        |- router        #  路由
            |- index.ts   
        |- store       #  数据管理
            |- index.ts   
        |- views       # 页面组件
            |- home     
               |- index.index
        |- App.vue      # 项目的主组件
        |- main.ts        # 入口ts文件
    | - index.html     # 入口html文件

2.各个页面内容

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>管理系统</title>
  </head>
  <body>
    <!-- 令 id="app" 便于vue进行挂载 -->
    <div id="app"></div>
    <!-- 引入main.ts文件 -->
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

App.vue

<template>
  <!-- 一般vue项目都会使用vue-router -->
  <router-view></router-view>
</template>
<script setup></script>

reset.less   对基础HTML默认样式的重置,这里引用一个开源项目:minireset.css

html,
body,
p,
ol,
ul,
li,
dl,
dt,
dd,
blockquote,
figure,
fieldset,
legend,
textarea,
pre,
iframe,
hr,
h1,
h2,
h3,
h4,
h5,
h6 {
  margin: 0;
  padding: 0;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  font-size: 100%;
  font-weight: normal;
}

ul {
  list-style: none;
}

button,
input,
select {
  margin: 0;
}

html {
  box-sizing: border-box;
}

*, *::before, *::after {
  box-sizing: inherit;
}

img,
video {
  height: auto;
  max-width: 100%;
}

iframe {
  border: 0;
}

table {
  border-collapse: collapse;
  border-spacing: 0;
}

td,
th {
  padding: 0;
}

router/index.ts

import { createRouter, createWebHashHistory, RouteRecordRaw, RouteRecordRaw } from 'vue-router';


// 配置路由
const routes: Array<RouteRecordRaw> = [{
  path: '/',
  name: 'Home',
  component: () => import('@/viwes/home/index.vue'),
  meta: {},
  children: [],
}];

const router = createRouter({
  history: createWebHashHistory(),
  routes,
});


export default router;

store/index.ts

  import { createPinia } from 'pinia';
  import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
  const pinia = createPinia();
  // 使用pinia数据持久化插件
  pinia.use(piniaPluginPersistedstate);
  export default pinia;

main.ts

import { createApp } from 'vue';
import App from './App.vue';
import router from '@/router';
import pinia from '@/store'; // ++
import './styles/reset.less';
const app = createApp(App);
app.use(router);
app.use(pinia); // ++
app.mount('#app');

http/request.ts

import axios from 'axios';
import type {
  AxiosInstance,
  AxiosRequestConfig,
  AxiosResponse,
  AxiosError,
  InternalAxiosRequestConfig,
} from 'axios';

const service: AxiosInstance = axios.create({
    baseURL: ''
    timeout: 5000,
  });

// axios实例拦截请求
service.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    return config;
  },
  (error: AxiosError) => {
    return Promise.reject(error);
  }
);

// axios实例拦截响应
service.interceptors.response.use(
  (response: AxiosResponse) => {
  },
  (error: any) => {
  }
);

export default service

基本内容搭建完成后,因为浏览器是不能识别Vue,TS,Sass这些语言的,还需要Vite将它们转变成浏览器可以识别的语言:Html,CSS,JS。

3.安装依赖

npm install -D vite @vitejs/plugin-vue @vitejs/plugin-vue-jsx

npm install -D @types/node vue-tsc
  • vite:项目构建工具
  • @vitejs/plugin-vue:使vite能够编译vue组件
  • @vitejs/plugin-vue-jsx:使vite能够编译jsx组件
  • @types/node:node类型包,使ts支持node
  • vue-tsc:vue文件的类型检查工具

 4.vite环境变量

Vite官方文档对环境变量的介绍:环境变量和模式 | Vite 官方中文文档 (vitejs.dev)

在项目根目录下新建三个文件.env.env.production.env.development

  • .env:所有情况下都会加载
  • .env.[mode]:只在指定模式下加载

 

.env 

# axios请求的 baseURL   环境变量名称必须与VITE_作为前缀,前缀可以在Vite配置中修改
VITE_APP_API_BASEURL = /api

request.ts

const service: AxiosInstance = axios.create({
  // 这样我们就可以在环境变量中改变 axios 的 baseURL
    baseURL: import.meta.env.VITE_APP_API_BASEURL
    timeout: 5000,
  });

//....

我们在开发过程中,环境变量可能会越来越多,我们可能想要获得智能的TypeScript语法提示来让我们知道有哪些环境变量。

在项目根目录下新建types文件夹

types/env.d.ts


interface ImportMetaEnv {
  // 我们每次添加完新的环境变量就在此添加一次ts类型
  // 这样我们就能在使用 import.meta.env 时获得ts语法提示
  readonly VITE_APP_API_BASEURL: string;
}

interface ImportMeta {
  readonly env: ImportMetaEnv;
}

vite配置文件

vite.config.ts

import { defineConfig, loadEnv } from 'vite';
import type { UserConfig, ConfigEnv } from 'vite';
import { fileURLToPath } from 'url';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';

export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
  // 获取当前工作目录
  const root = process.cwd();
  // 获取环境变量
  const env = loadEnv(mode, root);
  return {
    // 项目根目录 
    root,
    // 项目部署的基础路径
    base: '/',
    publicDir: fileURLToPath(new URL('./public', import.meta.url)), // 无需处理的静态资源位置
    assetsInclude: fileURLToPath(new URL('./src/assets', import.meta.url)), // 需要处理的静态资源位置
    plugins: [
      // Vue模板文件编译插件
      vue(),
      // jsx文件编译插件
      vueJsx(),
    ],
    // 运行后本地预览的服务器
    server: {
      // 是否开启https
      https: false,
      // 指定服务器应该监听哪个 IP 地址。 如果将此设置为 0.0.0.0 或者 true 将监听所有地址,包括局域网和公网地址。
      host: true,
      // 开发环境预览服务器端口
      port: 8000,
      // 启动后是否自动打开浏览器
      open: false,
      // 是否开启CORS跨域
      cors: true,
      // 代理服务器
      // 帮助我们开发时解决跨域问题
      proxy: {
        // 这里的意思是 以/api开头发送的请求都会被转发到 http://xxx:8000
        '/api': {
          target: 'http://xxx:8000',
          // 改变 Host Header
          changeOrigin: true,
          // 发起请求时将 '/api' 替换为 ''
          rewrite: (path) => path.replace(/^\/api/, ''),
        },
      },
    },
    // 打包配置
    build: {
      // 关闭 sorcemap 报错不会映射到源码
      sourcemap: false,
      // 打包大小超出 400kb 提示警告
      chunkSizeWarningLimit: 400,
      rollupOptions: {
        // 打包入口文件 根目录下的 index.html
        // 也就是项目从哪个文件开始打包
        input: {
          index: fileURLToPath(new URL('./index.html', import.meta.url)),
        },
        // 静态资源分类打包
        output: {
          format: 'esm',
          chunkFileNames: 'static/js/[name]-[hash].js',
          entryFileNames: 'static/js/[name]-[hash].js',
          assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
        },
      },
    },
    // 配置别名
    resolve: {
      alias: {
        '@': fileURLToPath(new URL('./src', import.meta.url)),
        '#': fileURLToPath(new URL('./types', import.meta.url)),
      },
    },
  };
});

ts配置文件     

  • 项目根目录下新建tsconfig.json
{
    "compilerOptions": {
        // 编译出JS的目标ES版本
        "target": "esnext",
        // 使用的ES版本
        "module": "esnext",
        "allowJs": false,
        // 用于选择模块解析策略,有'node'和'classic'两种类型
        "moduleResolution": "node",
        // 开启严格模式
        "strict": true,
        // 强制代码中使用的模块文件名必须和文件系统中的文件名保持大小写一致
        "forceConsistentCasingInFileNames": true,
        // 允许使用 xxx 代替 * as xxx 导入
        "allowSyntheticDefaultImports": true,
        // 指定 jsx 代码的生成: 'preserve', 'react-native', or 'react'
        "jsx": "preserve",
        // 用来指定编译时是否生成.map文件
        "sourceMap": true,
        // 通过为导入内容创建命名空间,实现CommonJS和ES模块之间的互操作性
        "esModuleInterop": true,
        // 是否可以导入 json module
        "resolveJsonModule": true,
        // 是否检测定义了但是没使用的变量
        "noUnusedLocals": true,
        // 是否检查是否有在函数体中没有使用的参数
        "noUnusedParameters": true,
        // 是否启用实验性的装饰器特性
        "experimentalDecorators": true,
        // ts中可以使用的库 这里配置为 dom 与 es模块
        "lib": [
            "dom",
            "esnext"
        ],
        // 不允许变量或函数参数具有隐式any类型
        "noImplicitAny": false,
        // 启用阻止对下载库的类型检查
        "skipLibCheck": true,
        // types用来指定需要包含的模块
        "types": [
            "vite/client",
            "element-plus/global"
        ],
        // 编译的时候删除注释
        "removeComments": true,
        // 使用绝对路径时使用baseUrl去解析导入路径
        "baseUrl": ".",
        // 为导入路径配置别名
        "paths": {
            "@/*": [
                "src/*"
            ],
            "#/*": [
                "types/*"
            ]
        },
        // 配置虚拟目录
        "rootDirs": []
    },
    // 指定需要编译文件
    "include": [
        "src/**/*.ts",
        "src/**/*.d.ts",
        "src/**/*.tsx",
        "src/**/*.vue",
        "types/**/*.d.ts",
        "types/**/*.ts",
        "build/**/*.ts",
        "build/**/*.d.ts",
        "mock/**/*.ts",
        "vite.config.ts"
    ],
    // 指定不需要编译的文件
    "exclude": [
        "node_modules",
        "dist",
        "**/*.js"
    ]
}

 /package.json

"scripts": {
   "dev": "vite --mode development",
   // 先进行语法检查 再进行项目打包
   "build": "vite build",
},

以上内容仅提供搭建思路。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值