vue3 + ts + vite + scss 建置行動裝置的H5

大家都知道,行動裝置喝pc端的區別在於的是,行動裝置怎麼做適配。還有vue3 和 ts 如何進行結合。本人抱著more interest, less interests的目的。來紀錄自己在開發過程中的一些公共的方面。來幫助更多的技術人.

效果

作為行動裝置最關鍵的頁面相容問題,在本專案是已經解決了的。
原始碼地址: https://github.com/cll123456/vue3-ts-mobile.git
演示地址: https://cll123456.github.io/vue3-ts-mobile/#/

安裝依賴

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
"browserslist": [
    "defaults", // 預設
    "last 2 versions", // 相容主流瀏覽器的最近兩個版本
    "> 1%", // 使用的瀏覽器需要在市場上的份額大於1
    "iOS 7", // ios 系統版本大於7
    "last 3 iOS versions" // 相容ios的最新3個版本
  ],
  "dependencies": {<!-- --> // 生產依賴
    "axios": "^0.21.1", // 發ajax 請求的包
    "vant": "^3.0.9",  // 安裝vant ui 庫
    "vue": "^3.0.5", // vue3 的版本
    "vue-router": "^4.0.4",  // 對應vue3 的 路由版本
    "vuex": "^4.0.0" // 對應vue3的vuex, 在這裡給一個溫馨提示。在vue3中,做資料的儲存,其實可以不需要使用vuex, 例如: provide/ reject 、 全域ref(變數) 都是可以的,這個根據實際專案的情況來決定
  },
  "devDependencies": {<!-- --> // 開發黃金依賴
    "@types/node": "^14.14.36", // node 環境的型別檢查
    "@vitejs/plugin-vue": "^1.1.5", // vite 的封裝vue3的包,
    "@vue/compiler-sfc": "^3.0.5", // vue3 編譯 .vue模板的包
    "autoprefixer": "^10.2.4", // 自動新增 css 的前置詞
    "postcss-pxtorem": "^5.1.1", // 用於將px 轉成rem 的包,在專案中就可以使用 px啦
    "sass": "^1.32.8", // sass 只要按照就行,用於css 的工程化
    "typescript": "^4.1.3", // ts
    "vite": "^2.0.5" // vite 工具
  }

主入口 vite.config.js

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
import {<!-- --> defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

// https://vitejs.dev/config/
export default defineConfig({<!-- -->
  plugins: [vue()],
  base:  './',//打包路徑
  // 別名
  resolve: {<!-- -->
    alias: {<!-- -->
      '@': path.resolve(__dirname, './src')//設定別名
    }
  },
  // 全域css
  css: {<!-- -->
    preprocessorOptions: {<!-- -->
      scss: {<!-- -->
      // 全域的scss ,跨域放多個,例如:主題的變數,和一些混合等
        additionalData: `@import "./src/style/mixin.scss";`,
      }
    }
  },
  // 代理服務
  server: {<!-- -->
    port: 4000,//啟動連接埠
    // open: true,
    proxy: {<!-- -->
      // 第一個代理
      '/api/mobile':{<!-- --> // 匹配到啥來進行方向代理
        target: 'https://github.com/cll123456/vue3-ts-mobile', // 代理的目標
        rewrite: (path) => path.replace(/^/api/, '') // 如果不需要api 直接把路徑上的api 取代成空,這個
      },
     
      // 第二個代理
      '/api/md': {<!-- -->
       target: 'https://editor.csdn.net/md?not_checkout=1&articleId=115252632',//代理網址
        changeOrigin: true, // 支援跨域
        rewrite: (path) => path.replace(/^/api/, '')
      }
    },
  },
})

ts 配置

Vite支援直接匯入.ts檔案。
Vite只對.ts檔案執行翻譯,不執行型別檢查。它假設型別檢查由IDE和構建過程負責(可以在構建腳本中執行tsc——noEmit)。
Vite使用esbuild將TypeScript轉換為JavaScript,比普通tsc快20~30倍,HMR更新可以在50毫秒內反映到瀏覽器中。
請注意,因為esbuild只執行不帶型別訊息的轉換,所以它不支援某些屬性,如const enum和隱式的純型別匯入。你必須在tsconfig中設定"isolatedModules": true。這樣TS就會對那些不能與單獨的翻譯一起工作的屬性發出警告。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  "compilerOptions": {<!-- --> // 編譯選項
    "target": "esnext", // ts的編譯的目標es的版本
    "module": "esnext", // 模組的版本是 esnext(下一階段,)
    "moduleResolution": "node", // 模組的解析 node的模組解析方式
    "strict": true, // 啟動嚴格的程式碼檢查
    "jsx": "preserve", // 使用的jsx 是轉化成怎麼的表現形式
    "sourceMap": true, // 打包後是否使用資源地圖,方便搜尋問題所在
    "resolveJsonModule": true, // 是否支援使用import 來匯入json檔案
    "isolatedModules":true, // 每一個檔案是否單獨編譯成一個檔案,這個在開發階段很重要,生產環境設定成false,因為vite是基於每一個檔案的改變來進行熱更新,如果不開啟這個選項,ts 改變後不會自動熱更新
    "esModuleInterop": true, // 是否啟動模組化與非模組化的檔案的互動
    "lib": ["esnext", "dom"], // 環境, dom 環境 和 最新的es
    "types": ["vite/client"]  //Vite應用程式中緩衝客戶端程式碼環境, 預設是node api
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"] // 這是需要轉換的程式碼目錄和副檔名名

解決頁面大小相容問題

新建立postcss.config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
module.exports = {<!-- -->
  plugins: {<!-- -->
    autoprefixer: {<!-- -->},
    'postcss-pxtorem': {<!-- -->
      // 數值|函式)表示根元素字型大小或根據input引數回傳根元素字型大小
      rootValue: 37.5,
      // 使用萬用字元*啟用所有屬性
      propList: ['*'],
      // 允許在媒體搜尋中轉換px
      mediaQuery: true,
      // 過濾掉.norem-開頭的class,不進行rem轉換
      selectorBlackList: ['.norem']
    },
  },
};

建立 rem.ts,用於根據當前的視窗來自動改變跟的font-size

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// rem等比適配設定檔
// 基準大小, 這個是由於vantui的基準大小就是37.5
const baseSize = 37.5
// 注意此值要與 postcss.config.js 檔案中的 rootValue保持一致
// 設定 rem 函式
function setRem() {<!-- -->
  // 當前頁面寬度相對於 375寬的縮放比例,可根據自己需要修改,一般設計稿都是寬750(圖方便可以拿到設計圖後改過來)。
  const scale = document.documentElement.clientWidth / 375
  // 設定頁面根節點字型大小(「Math.min(scale, 2)」 指最高放大比例為2,可根據實際業務需求調整)
  document.documentElement.style.fontSize = baseSize * Math.min(scale, 2) + 'px'
}
// 初始化
setRem()
// 改變視窗大小時重新設定 rem
window.onresize = function () {<!-- -->
  setRem()
}

export {<!-- -->}

初始化樣式

style 中建立 reset.scss

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
@charset "UTF-8";

/* stylelint-enable */
/* 重置樣式 */
* {
    -webkit-tap-highlight-color: transparent;
    outline: 0;
}

body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button, input, textarea, th, td {
    margin: 0;
    padding: 0;
    vertical-align: baseline;
}

img {
    border: 0 none;
    vertical-align: top;
}

i, em {
    font-style: normal;
}

ol, ul {
    list-style: none;
}

input, select, button, h1, h2, h3, h4, h5, h6 {
    font-size: 100%;
    font-family: inherit;
}

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

a, a:visited {
    text-decoration: none;
    color: #333;
}

body {
    margin: 0 auto;
    background: #e8e8ed;
    font-size: 14px;
    font-family: -apple-system,Helvetica,sans-serif;
    line-height: 1.5;
    color: #666;
    -webkit-text-size-adjust: 100% !important;
  /*-webkit-user-select: none;
  user-select: none;*/
}

使用路由 router

由於vue3的整改,路由的使用方式也發生了一些改變,具體檢視官網

1
2
3
4
5
6
7
8
9
10
11
12
13
import {<!-- --> createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
const routes: Array<RouteRecordRaw> = [
  {<!-- -->
    path: "/",
    name: "Home",
    component: () => import("../views/Home/index.vue"), // 使用懶載入
  },
];
const router = createRouter({<!-- -->
  history: createWebHashHistory(),
  routes
});
export default router;

mian.ts 的結合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import {<!-- --> createApp } from 'vue'
import App from './App.vue'
// 重置樣式
import './style/reset.scss'
import 'vant/lib/index.css'; // 全域引入樣式

// 引入 更改跟節點的size
import './rem'
import Vant from 'vant';
// 掛載路由
import router from "./router";


createApp(App)
.use(Vant)
.use(router)
.mount('#app')