一个Vue项目的基础模板||PC端+移动端适配

1
2
3
4
npm create vite@latest dodola -- --template vue-ts
cd dodola
npm install
npm run dev

转到根目录下后

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
├── dist/
└── src/
    ├── api
    │   └── ... // 抽取出API请求
    ├── assets/                    // 静态资源目录
    ├── common/                    // 通用类库目录
    ├── components/                // 公共组件目录
    ├── routers/                   // 路由配置目录
    ├── store/                     // pinia 状态管理目录
        ├── index.ts               // 导出 store 的地方
        ├── home.ts                // 模块
        └── user.ts                // 模块
    ├── style/                     // 通用 CSS 目录
    ├── utils/                     // 工具函数目录
    ├── views/                     // 页面组件目录
    ├── App.vue
    ├── main.ts
    ├── vite-env.d.ts
├── index.html
├── tsconfig.json                  // TypeScript 配置文件
├── vite.config.ts                 // Vite 配置文件
└── package.json

vite.config.ts中,设置@指向src、服务器启动端口、打包路径、代理等等设置

先进行path模板的安装:

1
npm i @types/node -D

如果需要使用代理的话,可以先下载:

1
npm i @vitejs/plugin-basic-ssl -D

或者这个:

1
npm i vite-plugin-mkcert -D

这两个二选一即可

1
npm i vue-router@4
1
npm i pinia
1
npm i axios

使用CSS预编译器Stylus

安装(按序选择就好)

1
2
3
4
npm i stylus -D
# or
npm i sass -D
npm i less -D

通过插件 unplugin-vue-componentsunplugin-auto-import 实现组件自动按需导入(推荐!)

1
npm i @varlet/import-resolver unplugin-vue-components unplugin-auto-import -D
1
npm i postcss-px-to-viewport -D

postcss.config.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
      viewportWidth: 375,
      unitPrecision: 6,
      unitToConvert: 'px',
      viewportUnit: 'vmin',
      fontViewportUnit: 'vmin',
      propList: ['*'],
    }
  }
}

组件库设计基于 375px 宽度设计稿,推荐使用 postcss 插件将 px 单位转换成 vmin 单位从而实现移动端适配。 在 webpack/vite 项目根路径下创建 postcss.config.js 并做如下配置之后 375px -> 100vmin

1
npm i @varlet/touch-emulator
1
npm install element-plus --save
1
npm i @varlet/ui -S

VsCode 插件市场搜索: varlet-vscode-extension

1
npm install --save-dev @arco-design/web-vue
1
npm i -D naive-ui
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
{
  "compilerOptions": {
    
    "paths":{
      "@/*": ["./src/*"]
    },

    "target": "ES2020",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "preserve",

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": [
    "src/**/*.ts", 
    "src/**/*.tsx", 
    "src/**/*.vue",
    
    "auto-imports.d.ts",
    "components.d.ts"
],
  "references": [{ "path": "./tsconfig.node.json" }]
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{
  "compilerOptions": {
    "composite": true,
    "skipLibCheck": true,
    "module": "ESNext",
    "moduleResolution": "bundler",
    "allowSyntheticDefaultImports": true,
    "strict": true
  },
  "include": ["vite.config.ts"]
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from "path"

import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite';

import { ArcoResolver, NaiveUiResolver } from 'unplugin-vue-components/resolvers';
import { VarletImportResolver } from '@varlet/import-resolver'

import basicSSL from '@vitejs/plugin-basic-ssl'

// https://vitejs.dev/config/
export default defineConfig({
  define: { // 定义全局变量替换方式
    'process.env': process.env,
    'process.env.NODE_ENV': '"development"',
    __APP_VERSION__: JSON.stringify(require('./package.json').version),
    __API_URL__: 'window.__backend_api_url',
  },
  plugins: [
    vue(),
    AutoImport({
      resolvers: [ArcoResolver()],
    }),
    Components({
      resolvers: [
        ArcoResolver({
          importStyle: 'less',
          sideEffect: true,
        }),
        NaiveUiResolver(),
        VarletImportResolver(),
      ],
    }),
  ],
  resolve: {
    alias: {
      "@": resolve(__dirname, "src"),	// 设置'@'指向'src'
    },
  },
  root: './',	// index.html所在的位置,即根目录
  base: './',	// 设置打包路径,用于嵌入式开发
  mode: process.env.NODE_ENV,	// 设置模式,'development' 用于开发,'production' 用于构建(见define中的process.env.NODE_ENV)

  publicDir: 'public',	// 设置静态资源目录
  cacheDir: 'node_modules/.vite',	// 设置缓存目录
  envDir: './',	// 设置环境变量目录

  css: {
    preprocessorOptions: {
      less: {
        modifyVars: {
          // 'primary-color': '#1890ff',
          // 'link-color': '#1890ff',
          // 'border-radius-base': '2px',
        },
        javascriptEnabled: true,
        math: 'parens-division',
      },
    },
  },

  server: {
    host: 'localhost',	// 设置服务器启动地址,默认为'localhost
    
    port: 5173,	// 设置服务器启动端号,如果端口已经被使用,Vite 会自动尝试下一个可用的端口,所以这可能不是开发服务器最终监听的实际端口。
    strictPort: false,	// 设置是否严格检查端口号
    
    open: false,	// 设置服务启动时是否自动打开浏览器
    cors: true,	// 允许跨域
    // proxy: {
    //   // 带选项写法:http://localhost:5173/api/bar -> http://jsonplaceholder.typicode.com/bar
    //   '/api': {
    //     target: 'http://jsonplaceholder.typicode.com',
    //     changeOrigin: true,
    //     rewrite: (path) => path.replace(/^\/api/, ''),
    //   },
    //   // 代理 websockets 或 socket.io 写法:ws://localhost:5173/socket.io -> ws://localhost:5174/socket.io
    //   '/socket.io': {
    //     target: 'ws://localhost:5174',
    //     ws: true,
    //   },
    // },
  },
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
      viewportWidth: 375,
      unitPrecision: 6,
      unitToConvert: 'px',
      viewportUnit: 'vmin',
      fontViewportUnit: 'vmin',
      propList: ['*'],
    }
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
{
  "name": "aixinmarket-frontend-2024",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "@varlet/import-resolver": "^3.0.7",
    "@varlet/touch-emulator": "^3.0.7",
    "@varlet/ui": "^3.0.7",
    "axios": "^1.6.7",
    "element-plus": "^2.6.1",
    "pinia": "^2.1.7",
    "vue": "^3.4.19",
    "vue-router": "^4.3.0"
  },
  "devDependencies": {
    "@arco-design/web-vue": "^2.54.6",
    "@types/node": "^20.11.25",
    "@vitejs/plugin-basic-ssl": "^1.1.0",
    "@vitejs/plugin-vue": "^5.0.4",
    "less": "^4.2.0",
    "naive-ui": "^2.38.1",
    "postcss-px-to-viewport": "^1.1.1",
    "stylus": "^0.63.0",
    "typescript": "^5.2.2",
    "unplugin-auto-import": "^0.17.5",
    "unplugin-vue-components": "^0.26.0",
    "vite": "^5.1.4",
    "vite-plugin-mkcert": "^1.17.4",
    "vue-tsc": "^1.8.27"
  }
}
1
2
3
/// <reference types="vite/client" />
// 类型声明
declare const __APP_VERSION__: string
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';

import './style.css';
import router from './routers';

import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

const pinia = createPinia()

createApp(App)
  .use(pinia)
  .use(router)
  .use(pinia)
  .use(ElementPlus)
  .mount('#app');

相关内容