vite2+ts+vite+pinia+elment plus+pnpm

第一步开始安装:

1
2
pnpm create vite vue3-ts-vite-pinia-element-plus-pnpm --template vue-ts
 ERROR  No package.json (or package.yaml, or package.json5) was found in "/home/xfhuang/workspace/node".

安装 pnpm

 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
 pc wget -qO- https://get.pnpm.io/install.sh | pc sh  -
==> Downloading pnpm binaries 8.1.1
 WARN  using --force I sure hope you know what you are doing
Copying pnpm CLI from /tmp/tmp.SJzIHrlcoP/pnpm to /home/xfhuang/.local/share/pnpm/pnpm
Appended new lines to /home/xfhuang/.zshrc

Next configuration changes were made:
export PNPM_HOME="/home/xfhuang/.local/share/pnpm"
case ":$PATH:" in
  *":$PNPM_HOME:"*) ;;
  *) export PATH="$PNPM_HOME:$PATH" ;;
esac

To start using pnpm, run:
source /home/xfhuang/.zshrc
 [Tue Apr 04 2023 11:02AM (CST+0800)] [1 day, 57 min] :~/workspace/node via  v16.15.0   took 35s
🌈 source /home/xfhuang/.zshrc
Seems robbyrussell/oh-my-zsh is already installed!
Seems zsh-users/zsh-syntax-highlighting is already installed!
Seems zsh-users/zsh-autosuggestions is already installed!
Seems zsh-users/zsh-completions is already installed!
Seems robbyrussell/oh-my-zsh is already installed!
Seems robbyrussell/oh-my-zsh is already installed!
Seems robbyrussell/oh-my-zsh is already installed!
Seems robbyrussell/oh-my-zsh is already installed!
Seems robbyrussell/oh-my-zsh is already installed!
Seems robbyrussell/oh-my-zsh is already installed!
Seems paulirish/git-open is already installed!
Seems robbyrussell/oh-my-zsh is already installed!
Seems robbyrussell/oh-my-zsh is already installed!
Seems zsh-users/zsh-syntax-highlighting is already installed!
Seems zsh-users/zsh-autosuggestions is already installed!
Seems zsh-users/zsh-completions is already installed!
Seems robbyrussell/oh-my-zsh is already installed!
 λ ls -all
   rwxr-xr-x   18   xfhuang   xfhuang      4 KiB   Tue Apr  4 10:54:23 2023    ./
   rwxr-xr-x   11   xfhuang   xfhuang      4 KiB   Tue Mar 21 14:28:56 2023    ../
   rwxr-xr-x    8   xfhuang   xfhuang      4 KiB   Wed Jul  6 17:34:29 2022    cloud-disk-ui/
   rwxr-xr-x    8   xfhuang   xfhuang      4 KiB   Fri Aug 12 09:50:47 2022    education-cloud-web-admin/
   rwxr-xr-x   17   xfhuang   xfhuang      4 KiB   Thu Jul 21 11:13:15 2022    education-cloud-web-ui/
   rwxr-xr-x    6   xfhuang   xfhuang      4 KiB   Mon Apr  3 13:48:52 2023    icMedia/
   rwxr-xr-x    3   xfhuang   xfhuang      4 KiB   Fri Oct 21 15:00:55 2022    kubegems-dashboard/
   rwxr-xr-x    6   xfhuang   xfhuang      4 KiB   Wed Aug 31 14:48:52 2022    mini-gde-frontend/
   rwxr-xr-x    6   xfhuang   xfhuang      4 KiB   Wed Aug 31 09:43:43 2022    mynode/
   rwxr-xr-x    3   xfhuang   xfhuang      4 KiB   Tue Oct 11 13:19:46 2022    nestjs/
   rwxr-xr-x    5   xfhuang   xfhuang      4 KiB   Mon Oct 17 13:24:09 2022    Node全栈项目开源/
   rw-r--r--    1   xfhuang   xfhuang      3 B     Tue Apr  4 10:54:23 2023    package.json
   rw-r--r--    1   xfhuang   xfhuang     83 B     Tue Apr  4 10:54:23 2023    package-lock.json
   rw-r--r--    1   xfhuang   xfhuang      1 KiB   Tue Apr  4 11:07:03 2023    .pnpm-debug.log
   rwxr-xr-x    3   xfhuang   xfhuang      4 KiB   Thu Feb  2 12:29:52 2023    sample-app/
   rwxr-xr-x   12   xfhuang   xfhuang      4 KiB   Tue Oct 11 10:28:16 2022    sf-midway-admin/
   rwxr-xr-x    8   xfhuang   xfhuang      4 KiB   Tue Oct 11 13:35:15 2022    sf-vue-admin/
   rwxr-xr-x    3   xfhuang   xfhuang      4 KiB   Tue Oct 11 11:29:41 2022    v2/
   rwxr-xr-x    4   xfhuang   xfhuang      4 KiB   Tue Jan 17 09:02:07 2023    vue3/
   rwxr-xr-x    8   xfhuang   xfhuang      4 KiB   Fri Feb 24 09:05:09 2023    vue3.0-template-admin/
   rwxr-xr-x    6   xfhuang   xfhuang      4 KiB   Fri Feb 24 09:05:30 2023    vue3-element-admin/
 [Tue Apr 04 2023 11:08AM (CST+0800)] [1 day,  1:03] :~/workspace/node via  v16.15.0
🌈 rm -rf package.json
 [Tue Apr 04 2023 11:08AM (CST+0800)] [1 day,  1:04] :~/workspace/node
🌈 rm -rf package-lock.json
 [Tue Apr 04 2023 11:08AM (CST+0800)] [1 day,  1:04] :~/workspace/node
🌈 rm -rf .pnpm-debug.log

 [Tue Apr 04 2023 11:14AM (CST+0800)] [1 day,  1:09] :~/workspace/node   took 1s
🌈 pnpm create vite vue3-ts-vite-pinia-element-plus-pnpm  --template vue-ts
.../share/pnpm/store/v3/tmp/dlx-310038   |   +1 +
Packages are hard linked from the content-addressable store to the virtual store.
  Content-addressable store is at: /home/xfhuang/.local/share/pnpm/store/v3
  Virtual store is at:             ../../.local/share/pnpm/store/v3/tmp/dlx-310038/node_modules/.pnpm
.../share/pnpm/store/v3/tmp/dlx-310038   | Progress: resolved 1, reused 0, downloaded 1, added 1, done

Scaffolding project in /home/xfhuang/workspace/node/vue3-ts-vite-pinia-element-plus-pnpm...

Done. Now run:

  cd vue3-ts-vite-pinia-element-plus-pnpm
  pnpm install
  pnpm run dev

接下来操作运行看看

 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
🌈   cd vue3-ts-vite-pinia-element-plus-pnpm
  pnpm install
  pnpm run dev
 WARN  deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
Packages: +50
++++++++++++++++++++++++++++++++++++++++++++++++++
Packages are copied from the content-addressable store to the virtual store.
  Content-addressable store is at: /home/xfhuang/.local/share/pnpm/store/v3
  Virtual store is at:             node_modules/.pnpm
Downloading registry.npmmirror.com/typescript/4.9.3: 11.6 MB/11.6 MB, done
node_modules/.pnpm/registry.npmmirror.com+esbuild@0.17.15/node_modules/esbuild: Running postinstall script, done in 54ms
Progress: resolved 72, reused 0, downloaded 50, added 50, done

dependencies:
+ vue 3.2.47

devDependencies:
+ @vitejs/plugin-vue 4.1.0
+ typescript 4.9.3 (5.0.3 is available)
+ vite 4.2.0 (4.2.1 is available)
+ vue-tsc 1.2.0

Done in 4.4s

> vue3-ts-vite-pinia-element-plus-pnpm@0.0.0 dev /home/xfhuang/workspace/node/vue3-ts-vite-pinia-element-plus-pnpm
> vite


  VITE v4.2.0  ready in 241 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h to show help

点开浏览器可以看到界面即可。

必要依赖安装

element-plus

命令: pnpm install element-plus

执行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
 λ pnpm install element-plus
 WARN  deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
Packages: +21
+++++++++++++++++++++
Downloading registry.npmmirror.com/element-plus/2.3.2: 7.94 MB/7.94 MB, done
node_modules/.pnpm/registry.npmmirror.com+vue-demi@0.13.11_vue@3.2.47/node_modules/vue-demi: Running postinstall script, done in 83ms
Progress: resolved 93, reused 50, downloaded 21, added 21, done

dependencies:
+ element-plus 2.3.2

Done in 6.6s

@element-plus/icons-vue

命令: pnpm install @element-plus/icons-vue

执行:

1
2
3
4
5
6
7
8
9
pnpm install @element-plus/icons-vue
 WARN  deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
Already up to date

dependencies:
+ @element-plus/icons-vue 2.1.0

Progress: resolved 93, reused 71, downloaded 0, added 0, done
Done in 1.2s

axios

命令: pnpm install axios

执行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
pnpm install axios
 WARN  deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
Packages: +9
+++++++++
Progress: resolved 102, reused 71, downloaded 9, added 9, done

dependencies:
+ axios 1.3.4

Done in 1.7s

pinia

命令: pnpm install pinia

执行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
 pnpm install pinia
 WARN  deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
Packages: +2
++
Progress: resolved 104, reused 80, downloaded 2, added 2, done

dependencies:
+ pinia 2.0.33

Done in 1.6s

vue-router

命令: pnpm install vue-router

执行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
 pnpm install vue-router
 WARN  deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
Packages: +1
+
Progress: resolved 105, reused 82, downloaded 1, added 1, done

dependencies:
+ vue-router 4.1.6

Done in 1.5s

sass

命令: pnpm install -D sass

执行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
pnpm install -D sass
 WARN  deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
Packages: +17 -1
+++++++++++++++++-
Progress: resolved 121, reused 83, downloaded 16, added 17, done

devDependencies:
+ sass 1.60.0

Done in 2.3s

eslint

命令:pnpm install -D eslint

执行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
 pnpm install -D eslint
 WARN  deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
Packages: +94
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Progress: resolved 215, reused 99, downloaded 94, added 94, done

devDependencies:
+ eslint 8.37.0

Done in 3.8s

Next:

  1. 使用 eslint 自动进行配置

    命令:./node_modules/.bin/eslint --init

    执行:

     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
    
    ----------------------------------- Questions ----------------------------------------
    $ ./node_modules/.bin/eslint --init
    You can also run this command directly using 'npm init @eslint/config'.
    npx: 40 安装成功,用时 3.22 
    1.
    ? How would you like to use ESLint? ...
      To check syntax only
      To check syntax and find problems
    > To check syntax, find problems, and enforce code style
    2.
    ? What type of modules does your project use? ...
    > JavaScript modules (import/export)
      CommonJS (require/exports)
      None of these
    3.
    ? Which framework does your project use? ...
      React
    > Vue.js
      None of these
    4.
    ? Does your project use TypeScript? » No / >Yes
    5.
    ? Where does your code run? ...  (Press <space> to select, <a> to toggle all, <i> to invert selection)
    >  Browser
     Node
    6.
    ? How would you like to define a style for your project? ...
    > Use a popular style guide
      Answer questions about your style
    7.
    ? Which style guide do you want to follow? ...
    > Standard: https://github.com/standard/eslint-config-standard-with-typescript
      XO: https://github.com/xojs/eslint-config-xo-typescript
    8.
    ? What format do you want your config file to be in? ...
    > JavaScript
      YAML
      JSON
    
    Checking peerDependencies of eslint-config-standard-with-typescript@latest
    The config that you've selected requires the following dependencies:
    
    eslint-plugin-vue@latest eslint-config-standard-with-typescript@latest @typescript-eslint/eslint-plugin@^5.0.0 eslint@^8.0.1 eslint-plugin-import@^2.25.2 eslint-plugin-n@^15.0.0 eslint-plugin-promise@^6.0.0 typescript@*
    9.
    ? Would you like to install them now? » No / > Yes
    10.
    ? Which package manager do you want to use? ...
      npm
      yarn
    > pnpm
    ----------------------------------- Result -------------------------------------
    $ ./node_modules/.bin/eslint --init
    You can also run this command directly using 'npm init @eslint/config'.
    npx: 40 安装成功,用时 3.22 
     How would you like to use ESLint? · style
     What type of modules does your project use? · esm
     Which framework does your project use? · vue
     Does your project use TypeScript? · No / Yes
     Where does your code run? · browser
     How would you like to define a style for your project? · guide
     Which style guide do you want to follow? · standard-with-typescript
     What format do you want your config file to be in? · JavaScript
    Checking peerDependencies of eslint-config-standard-with-typescript@latest
    The config that you've selected requires the following dependencies:
    
    eslint-plugin-vue@latest eslint-config-standard-with-typescript@latest @typescript-eslint/eslint-plugin@^5.0.0 eslint@^8.0.1 eslint-plugin-import@^2.25.2 eslint-plugin-n@^15.0.0 eslint-plugin-promise@^6.0.0 typescript@*
     Would you like to install them now? · No / Yes
     Which package manager do you want to use? · pnpm
    Installing eslint-plugin-vue@latest, eslint-config-standard-with-typescript@latest, @typescript-eslint/eslint-plugin@^5.0.0, eslint@^8.0.1, eslint-plugin-import@^2.25.2, eslint-plugin-n@^15.0.0, eslint-plugin-promise@^6.0.0, typescript@*
    Already up-to-date
    Progress: resolved 298, reused 277, downloaded 0, added 0, done
    Successfully created .eslintrc.cjs file in F:\Web\Vue\vue3-ts-vite-pinia-element-plus-pnpm
    

result:

  1. 检查项目目录出现 .eslintrc.cjs 文件

  2. 检查 package.json,出现一堆 eslint 相关依赖

  3. 1
    2
    3
    4
    5
    
        "@typescript-eslint/eslint-plugin": "^5.57.1",
        "@typescript-eslint/parser": "^5.57.1",
        "@vitejs/plugin-vue": "^4.1.0",
        "eslint": "^8.37.0",
        "eslint-plugin-vue": "^9.10.0",
    

prettier

命令: pnpm install -D --save-exact prettier

执行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
 pnpm install -D --save-exact prettier
 WARN  deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
Packages: +1
+
Progress: resolved 250, reused 227, downloaded 1, added 1, done

devDependencies:
+ prettier 2.8.7

Done in 2.2s

Next:

  1. 创建空的配置文件:echo {}> .prettierrc.json

  2. 创建 prettier 格式化忽略配置文件:.prettierignore

  3. .prettierignore 文件中添加如下初始配置

  4. 1
    2
    3
    
    # Ignore artifacts:
    build
    coverage
    

    格式化

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    🌈 npx prettier --write .
    .eslintrc.cjs 44ms
    .prettierrc.json 3ms
    .vscode/extensions.json 2ms
    index.html 37ms
    package.json 3ms
    pnpm-lock.yaml 379ms
    README.md 41ms
    src/App.vue 168ms
    src/components/HelloWorld.vue 26ms
    src/main.ts 6ms
    src/style.css 13ms
    src/vite-env.d.ts 5ms
    tsconfig.json 4ms
    tsconfig.node.json 1ms
    vite.config.ts 5ms
    

    安装 hook

     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
    
     λ pnpm install -D husky lint-staged
    WARN deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
    Packages: +55
    +++++++++++++++++++++++++++++++++++++++++++++++++++++++
    Progress: resolved 305, reused 228, downloaded 55, added 55, done
    
    devDependencies:
    + husky 8.0.3
    + lint-staged 13.2.0
    
    Done in 4.1s
     [Tue Apr 04 2023 12:46PM (CST+0800)] [1 day,  2:42] :~/workspace/node/vue3-ts-vite-pinia-element-plus-pnpm via  v19.8.1   took 4s
    🌈 npx husky install
    fatal: not a git repository (or any of the parent directories): .git
    husky - git command not found, skipping install
     [Tue Apr 04 2023 12:46PM (CST+0800)] [1 day,  2:42] :~/workspace/node/vue3-ts-vite-pinia-element-plus-pnpm via  v19.8.1
    🌈 git init
    Initialized empty Git repository in /home/xfhuang/workspace/node/vue3-ts-vite-pinia-element-plus-pnpm/.git/
     [Tue Apr 04 2023 12:46PM (CST+0800)] [1 day,  2:42] :~/workspace/node/vue3-ts-vite-pinia-element-plus-pnpm  🍣 main 🛤️  ×14via  v19.8.1
    🌈 npx husky install
    husky - Git hooks installed
     [Tue Apr 04 2023 12:46PM (CST+0800)] [1 day,  2:42] :~/workspace/node/vue3-ts-vite-pinia-element-plus-pnpm  🍣 main 🛤️  ×14via  v19.8.1
    🌈 npm set-script prepare "husky install"
    Unknown command: "set-script"
    
    Did you mean this?
        npm run-script # Run arbitrary package scripts
    
    To see a list of supported npm commands, run:
      npm help
    [1 - ERROR] [Tue Apr 04 2023 12:47PM (CST+0800)] [1 day,  2:42] :~/workspace/node/vue3-ts-vite-pinia-element-plus-pnpm  🍣 main 🛤️  ×14via  v19.8.1
     λ pnpm set-script prepare "husky install"
    Unknown command: "set-script"
    
    Did you mean this?
        npm run-script # Run arbitrary package scripts
    
    To see a list of supported npm commands, run:
      npm help
    [1 - ERROR] [Tue Apr 04 2023 12:47PM (CST+0800)] [1 day,  2:43] :~/workspace/node/vue3-ts-vite-pinia-element-plus-pnpm  🍣 main 🛤️  ×14via  v19.8.1
     λ npm set-script prepare "husky install"
    Unknown command: "set-script"
    
    Did you mean this?
        npm run-script # Run arbitrary package scripts
    
    To see a list of supported npm commands, run:
      npm help
    [1 - ERROR] [Tue Apr 04 2023 12:51PM (CST+0800)] [1 day,  2:46] :~/workspace/node/vue3-ts-vite-pinia-element-plus-pnpm  🍣 main 🛤️  ×14via  v19.8.1
     λ code .
     [Tue Apr 04 2023 12:51PM (CST+0800)] [1 day,  2:46] :~/workspace/node/vue3-ts-vite-pinia-element-plus-pnpm  🍣 main 🛤️  ×14via  v19.8.1   took 1s
    🌈  npm set-script prepare "husky install"
    Unknown command: "set-script"
    
    Did you mean this?
        npm run-script # Run arbitrary package scripts
    
    To see a list of supported npm commands, run:
      npm help
    [1 - ERROR] [Tue Apr 04 2023 12:54PM (CST+0800)] [1 day,  2:49] :~/workspace/node/vue3-ts-vite-pinia-element-plus-pnpm  🍣 main 🛤️  ×14via  v19.8.1
     λ npm pkg set scripts.prepare="husky install"
     [Tue Apr 04 2023 12:56PM (CST+0800)] [1 day,  2:52] :~/workspace/node/vue3-ts-vite-pinia-element-plus-pnpm  🍣 main 🛤️  ×14via  v19.8.1
    🌈 npx husky add .husky/pre-commit "npx lint-staged"
    husky - created .husky/pre-commit
    

image-20230404130101320

eslint-config-prettier

命令: pnpm install -D eslint-config-prettier

执行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
 pnpm install -D eslint-config-prettier
 WARN  deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
Packages: +1
+
Progress: resolved 306, reused 283, downloaded 1, added 1, done

devDependencies:
+ eslint-config-prettier 8.8.0

Done in 3.1s

添加 prettier

image-20230404131208345

@types/node

命令: pnpm install -D @types/node

执行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
 pnpm install -D @types/node
 WARN  deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
Packages: +2 -1
++-
Progress: resolved 307, reused 284, downloaded 1, added 2, done

devDependencies:
+ @types/node 18.15.11

Done in 2.5s

备注:此依赖是 node 中的类型定义,在后面对于一些配置信息时需要使用 node 中的方法时,没有引入此依赖就会提示安装。

3. 基础配置

1. 添加环境变量配置文件

1. 根据 <开发版本> | <预发行版> | <生产版本> 创建单独的 .env 文件

  • .env : 基本配置项
  • .env.development : 开发环境配置项
  • .env.staging : 预发布版本配置项
  • .env.production : 生产环境配置项
1
2
# windows 批处理命令(在项目根目录cmd窗运行下面命令即可生成上述四个文件):
echo '# DEFAULT ENV'> .env;echo '# DEVELOPMENT ENV'> .env.development;echo '# STAGING DEV'> .env.staging;echo '# PRODUCTION ENV'> .env.production

修改.env 文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# DEFAULT ENV

# 项目标题
VITE_APP_TITLE = 'My App'

# 项目运行端口
VITE_PORT = '3000'

# 项目启动后自动打开默认浏览器
VITE_OPEN = 'true'

2. 修改 vite 配置文件 vite.config.js

  1. 设置模块引入路径别名 "@"

首先需要在 vite.config.js 添加别名和对应的路径信息

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path';

// https://vitejs.dev/config/
export default defineConfig(({command, mode}) => {
  return {
    resolve:{
      alias: {
        "@": resolve(__dirname, "./src")
      }
    },
    plugins: [vue()]
  }
})

然后在 tsconfig.json 文件中添加别名的配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
  "compilerOptions": {
    "target": "ESNext",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "strict": true,
    "jsx": "preserve",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "esModuleInterop": true,
    "lib": ["ESNext", "DOM"],
    "skipLibCheck": true,
    "noEmit": true,
    //add
    "baseUrl": "./",
    "paths": {
       "@/*": ["src/*"]
     }
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
  "references": [{ "path": "./tsconfig.node.json" }]
}
  1. 将 env 文件中定义的配置添加到 vite 配置信息中
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
export default defineConfig(({command, mode}) => {

  const env = loadEnv(mode, process.cwd(), '');
  return {
    resolve:{
      alias: {
        "@": resolve(__dirname, "./src")
      }
    },
    server:{
      port: env.VITE_PORT, // 注意此时ts会提示VITE_PORT类型不符合
      open: env.VITE_OPEN
    },
    plugins: [vue()]
  }
})

由于 ts 无法识别.env 中的配置信息的类型,默认都是 string 类型,所以需要添加类型声明文件

按照文档中提示,在项目的 src 目录下创建 env.d.ts 文件,由于创建项目的时候,已经自动在目录下生成了 vite-env.d.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
/// <reference types="vite/client" />
/// <reference types="vite/client" />

declare module '*.vue' {
    import type { DefineComponent } from 'vue'
    const component: DefineComponent<{}, {}, any>
    export default component
  }

  // +++
  // * Vite Env 返回数据类型
  declare type Recordable<T = any> = Record<string, T>;


  interface ViteEnv {
    readonly VITE_APP_TITLE: string;
    readonly VITE_PORT: number;
    readonly VITE_OPEN: boolean;
    // 更多环境变量...
  }

  interface ImportMeta {
    readonly env: ViteEnv
  }
  // +++

添加了上面的信息后,回到 vite.config.ts 中,依然提示上面类型问题,所以此处写一个转换函数,将结果输出为我们定义的类型

在 src 目录下创建 utils 目录,然后创建 getEnv.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import fs from "fs";
import path from "path";


// 在 .env 文件中读取配置信息,并转换为 vite-env.d.ts 文件中声明类型的值
export function wrapperEnv(env: Recordable): ViteEnv {
    const ret: any = {};
    for (const envName of Object.keys(env)) {
        let envValue = env[envName].replace(/\\n/g, "\n");
        envValue = envValue === "true" ? true : envValue === "false" ? false : envValue;

        if (envName === "VITE_PORT") {
            envValue = Number(envValue);
        }

        ret[envName] = envValue;
        process.env[envName] = envValue;
    }
    return ret;
}

添加了上面内容后,发现在 vite.config.ts 中无法引入此 wrapperEnv 函数,ts 无法自动识别并提示,同时手动添加导入信息会提示

其作用是可以将程序分割为更小的模块,然后统一进行管理和编译,因为我并不了解所以具体内容自行查阅, 而此处主要使用用于对 node 环境下,运行的 vite.config.ts 进行的配置,在文件中填写包含的文件即创建的 getEnv.ts,就可以在 vite.config.ts 中正常的引入 getEnv 函数了,同时也可以自动导入函数。例如在 tsonfig.node.json 中添加 src/utils/getEnv.ts

1
2
3
4
5
6
7
8
9
{
  "compilerOptions": {
    "composite": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "allowSyntheticDefaultImports": true
  },
  "include": ["vite.config.ts","src/utils/getEnv.ts"]
}

修改后的 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
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path';
import { wrapperEnv } from './src/utils/getEnv';

// https://vitejs.dev/config/
export default defineConfig(({command, mode}) => {

  const env = loadEnv(mode, process.cwd(), '');
  const viteEnv = wrapperEnv(env);

  return {
    resolve:{
      alias: {
        "@": resolve(__dirname, "./src")
      }
    },
    server:{
      port: viteEnv.VITE_PORT,
      open: viteEnv.VITE_OPEN
    },
    plugins: [vue()]
  }
})

运行 npm run dev 既可以看到 localhost:3000

4. 配置 element-plus

  1. 全局注册 element-plus 组件(因为我现在并不是很在乎打包大小) 011B055E.png

1661147666394.png

  1. 将 element-plus 组件默认语言设置为中文简体

1661148179946.png

  1. 将 element 的 icon 组件全局注册 1661147643641.png

代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import 'element-plus/dist/index.css'
import './style.css'
import App from './App.vue'

const app = createApp(App)

// 注册 Element-Plus
app.use(ElementPlus, {
  locale: zhCn
})
// 注册 Element-Plus Icon 组件
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.component(key, component)
}

app.mount('#app')

按需引入(本项目使用此方式)

自动导入要使用的组件,首先需求安装 unplugin-vue-components 和 unplugin-auto-import 这两个插件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
🌈 pnpm install -D unplugin-vue-components unplugin-auto-import
 WARN  deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
Packages: +21
+++++++++++++++++++++
Progress: resolved 328, reused 285, downloaded 21, added 21, done

devDependencies:
+ unplugin-auto-import 0.15.2
+ unplugin-vue-components 0.24.1

Done in 3.1s

再 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
import { defineConfig, loadEnv } 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 { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { wrapperEnv } from './src/utils/getEnv';

// https://vitejs.dev/config/
export default defineConfig(({command, mode}) => {

  const env = loadEnv(mode, process.cwd(), '');
  const viteEnv = wrapperEnv(env);

  return {
    resolve:{
      alias: {
        "@": resolve(__dirname, "./src")
      }
    },
    server:{
      port: viteEnv.VITE_PORT,
      open: viteEnv.VITE_OPEN
    },
    plugins: [
      vue(),
      AutoImport({
        resolvers: [ElementPlusResolver()],
      }),
      Components({
        resolvers: [ElementPlusResolver()],
      }),
    ]
  }
})

使用 svg 图标

Element Plus 图标库有时满足不了实际开发需求,可以引用和使用第三方图标库,例如 iconfont,这里介绍下通过 vite-plugin-svg-icons 插件如何使用第三方图标库。

安装 vite-plugin-svg-icons

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
 pnpm install vite-plugin-svg-icons -D

 WARN  deprecated stable@0.1.8: Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility
 WARN  deprecated source-map-resolve@0.5.3: See https://github.com/lydell/source-map-resolve#deprecated
 WARN  deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
 WARN  deprecated source-map-url@0.4.1: See https://github.com/lydell/source-map-url#deprecated
 WARN  deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
 WARN  deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
Packages: +147
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Progress: resolved 475, reused 306, downloaded 147, added 147, done

devDependencies:
+ vite-plugin-svg-icons 2.0.1

Done in 4.8s

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
import { defineConfig, loadEnv } 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 { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import { wrapperEnv } from './src/utils/getEnv';

// https://vitejs.dev/config/
export default defineConfig(({command, mode}) => {

  const env = loadEnv(mode, process.cwd(), '');
  const viteEnv = wrapperEnv(env);
  const root = process.cwd()

  return {
    resolve:{
      alias: {
        "@": resolve(__dirname, "./src")
      }
    },
    server:{
      port: viteEnv.VITE_PORT,
      open: viteEnv.VITE_OPEN
    },
    plugins: [
      vue(),
      AutoImport({
        resolvers: [ElementPlusResolver()],
      }),
      Components({
        resolvers: [ElementPlusResolver()],
      }),
      createSvgIconsPlugin({
        // 指定需要缓存的图标文件夹
        iconDirs: [resolve(root, 'src/assets/icons')],
        // 指定symbolId格式
        symbolId: 'icon-[dir]-[name]',
      })
    ]
  }
})

在 main.ts 中引入注册脚本

1
2
// src/main.ts
import 'virtual:svg-icons-register'

新建图标文件夹

创建 src/assets/icons 文件夹,存放 svg 图标

image-20230404142757976

TypeScript 支持

1
2
3
4
5
6
// tsconfig.json
{
  "compilerOptions": {
    "types": ["vite-plugin-svg-icons/client"]
  }
}

封装组件

 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
<!-- src\components\SvgIcon.vue -->
<template>
  <svg aria-hidden="true" class="svg-icon">
    <use :xlink:href="symbolId" :fill="color" />
  </svg>
</template>

<script lang="ts" setup>
  import { computed } from 'vue'

  const props = defineProps({
    prefix: {
      type: String,
      default: 'icon'
    },
    iconClass: {
      type: String,
      required: true
    },
    color: {
      type: String,
      default: ''
    }
  })
  const symbolId = computed(() => `#${props.prefix}-${props.iconClass}`)
</script>

<style lang="scss" scoped>
  .svg-icon {
    width: 1em;
    height: 1em;
    vertical-align: -0.15em;
    overflow: hidden;
    fill: currentColor;
  }
</style>

展示效果如下:

image-20230404143032586

集成 Vue Router

安装 vue-router

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
 pnpm install vue-router@next
 WARN  deprecated stable@0.1.8: Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility
 WARN  deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
 WARN  deprecated source-map-resolve@0.5.3: See https://github.com/lydell/source-map-resolve#deprecated
 WARN  deprecated source-map-url@0.4.1: See https://github.com/lydell/source-map-url#deprecated
 WARN  deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
 WARN  deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
Packages: +1 -1
+-
Progress: resolved 475, reused 452, downloaded 1, added 1, done

dependencies:
- vue-router 4.1.6
+ vue-router 4.0.13 (4.1.6 is available)

Done in 2.9s

新建 src/router/index.ts 文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// src/router/index.ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import Index from "@/views/Index.vue"
import HomeVue from "@/views/User.vue"
const routes: Array<RouteRecordRaw> = [
//   {
//     path: '/',
//     name: 'home',
//     component: () => import('@/views/layout/index.vue')
//   }
{ path: '/', component: HomeVue },
{ path: '/about', component: Index },
]

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

export default router

在 main.ts 文件中挂载路由配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import 'element-plus/dist/index.css'
import './style.css'
import App from './App.vue'
import 'virtual:svg-icons-register'
import router from '@/router/index'

const app = createApp(App);
app.use(router)

// 注册 Element-Plus
app.use(ElementPlus, {
  locale: zhCn,
});
// 注册 Element-Plus Icon 组件
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.component(key, component)
}

app.mount('#app');

使用 router-view 修改 App.vue

 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
<script setup lang="ts">
import HelloWorld from "./components/HelloWorld.vue";
</script>

<template>
  <div>
    <a href="https://vitejs.dev" target="_blank">
      <img src="/vite.svg" class="logo" alt="Vite logo" />
    </a>
    <a href="https://vuejs.org/" target="_blank">
      <img src="./assets/icons/vue.svg" class="logo vue" alt="Vue logo" />
    </a>
  </div>
  <!-- <HelloWorld msg="Vite + Vue" />
  <Index />
  <User /> -->
  <RouterLink to="/">Home</RouterLink>
  <br/>
  <RouterLink to="/about">About</RouterLink>
  <router-view/>
</template>

<style scoped>
.logo {
  height: 6em;
  padding: 1.5em;
  will-change: filter;
  transition: filter 300ms;
}
.logo:hover {
  filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {
  filter: drop-shadow(0 0 2em #42b883aa);
}
</style>

这样才能使用 router

集成 Pinia

Pinia 是 Vue.js 的轻量级状态管理库,Vuex 的替代方案。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// src/main.ts

// 安装后导入
import { createPinia } from 'pinia'

// 创建 pinia 实例
const pinia = createPinia()

// 挂载
app.use(pinia)

pinia 模块封装

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// src/store/modules/user.ts
import { defineStore } from 'pinia'

const useUserStore = defineStore({
  id: 'user',
  state: () => ({
    count: 0,
  }),
  getters: {
    double: (state) => state.count * 2,
  },
  actions: {
    increment() {
      this.count++
    },
  },
})

export default useUserStore

view 创建 User

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<script setup lang="ts">
import useStore from '@/store'

const { user } = useStore()
</script>

<template>
  <div>count: {{ user.count }}</div>
  <div>double: {{ user.double }}</div>
  <el-button @click="user.increment">add+</el-button>
</template>

<style scoped></style>

显示效果

image-20230404144109417

八、集成 Axios

①、安装 axios

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
 pnpm install axios
 WARN  deprecated stable@0.1.8: Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility
 WARN  deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
 WARN  deprecated source-map-resolve@0.5.3: See https://github.com/lydell/source-map-resolve#deprecated
 WARN  deprecated source-map-url@0.4.1: See https://github.com/lydell/source-map-url#deprecated
 WARN  deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
 WARN  deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
Already up to date
Progress: resolved 475, reused 453, downloaded 0, added 0, done
Done in 2.4s

axios 封装

在 src 目录下创建 utils 目录存储日常工具函数等,axios 作为 HTTP 工具,我们创建 http.ts 作为 axios 配置文件。

  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
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
// src/utils/http.ts
import { useRouter } from 'vue-router'
import Axios, { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'
import { ResponseData } from '@/types/ResponseData'
import { ElMessage } from 'element-plus'
const router = useRouter()

// 创建 axios 实例
const axios = Axios.create({
  // API 请求的默认前缀
  baseURL: import.meta.env.VITE_API_BASE_URL,
  // 请求超时时间
  timeout: 20000,
  headers: { 'Content-Type': 'application/json;charset=utf-8' }
})

// 前置拦截器 发起请求之前的拦截
axios.interceptors.request.use(
  async (config: AxiosRequestConfig) => {
    return config
  },
  (error) => {
    return Promise.reject(error)
  }
)

/**
 * 异常拦截处理器
 * @param {*} error
 */
const errorHandler = (error: AxiosError) => {
  // 判断是否是响应错误信息
  if (error.response) {
    if (error.response.status == 401) {
      ElMessage.error('登录已过期,请您重新登录!')
      localStorage.clear()
      router.push('/login')
    } else if (error.response.status == 405) {
      ElMessage.error('您没有此功能的操作权限!')
    }
  }
  return Promise.reject(error)
}

// 后置拦截器 获取到响应时的拦截
axios.interceptors.response.use((response: AxiosResponse<ResponseData>) => {
  return response.data
}, errorHandler)

export default axios

/**
 * GET 请求
 * @param url
 * @param config
 * @returns
 */
export const get = <T = any, R = ResponseData<T>>(
  url: string,
  config?: AxiosRequestConfig
): Promise<R> => {
  return axios.get(url, config)
}

/**
 * POST 请求
 * @param url
 * @param data
 * @param config
 * @returns
 */
export const post = <T = any, R = ResponseData<T>>(
  url: string,
  data?: any,
  config?: AxiosRequestConfig
): Promise<R> => {
  return axios.post(url, data, config)
}

/**
 * delete 删除
 * @param url
 * @param config
 * @returns
 */
export const deleteHttp = <T = any, R = ResponseData<T>>(
  url: string,
  config?: AxiosRequestConfig
): Promise<R> => {
  return axios.delete(url, config)
}

/**
 * put
 * @param url
 * @param data
 * @param config
 * @returns
 */
export const put = <T = any, R = ResponseData<T>>(
  url: string,
  data?: any,
  config?: AxiosRequestConfig
): Promise<R> => {
  return axios.put(url, data, config)
}

创建 ts 文件,传入泛型 T 声明返回数据类型

1
2
3
4
5
6
// src/types/ResponseData.ts
export interface ResponseData<T = any> {
  code: number
  message: string
  data: T
}

API 封装

1
2
3
4
5
6
7
8
// src/api/auth/login.ts
import { post } from '@/utils/http'
import { TokenData, LoginParams } from '@/types/Auth'

// 登录服务接口
export const ServeLogin = (data: LoginParams) => {
  return post<TokenData>('/api/v1/auth/login', data)
}

新建文件 src/types/Auth.ts,定义登录接口入参类型及返回数据类型。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// src/types/Auth.ts
export interface TokenData {
  access_token: string
  expires_in: number
  type: string
}

export interface LoginParams {
  username: string
  password: string
}

API 调用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<script setup lang="ts">
import { ServeLogin } from '@/api/auth/login';

const login = async () => {
  const res = await ServeLogin({
    username: 'Jenny',
    password: '******'
  })
  console.log(res)
}

login()
</script>

集成 sass

新建 src/assets/styles/reset.scss 文件,将最新版本的 reset css 复制过来。

最新版本地址:The New CSS Reset | the-new-css-reset

 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
87
88
89
90
91
92
93
94
95
96
97
98
99
/***
    The new CSS reset - version 1.8.4 (last updated 14.2.2023)
    GitHub page: https://github.com/elad2412/the-new-css-reset
***/

/*
    Remove all the styles of the "User-Agent-Stylesheet", except for the 'display' property
    - The "symbol *" part is to solve Firefox SVG sprite bug
 */
 *:where(:not(html, iframe, canvas, img, svg, video, audio):not(svg *, symbol *)) {
    all: unset;
    display: revert;
}

/* Preferred box-sizing value */
*,
*::before,
*::after {
    box-sizing: border-box;
}

/* Reapply the pointer cursor for anchor tags */
a, button {
    cursor: revert;
}

/* Remove list styles (bullets/numbers) */
ol, ul, menu {
    list-style: none;
}

/* For images to not be able to exceed their container */
img {
    max-inline-size: 100%;
    max-block-size: 100%;
}

/* removes spacing between cells in tables */
table {
    border-collapse: collapse;
}

/* Safari - solving issue when using user-select:none on the <body> text input doesn't working */
input, textarea {
    -webkit-user-select: auto;
}

/* revert the 'white-space' property for textarea elements on Safari */
textarea {
    white-space: revert;
}

/* minimum style to allow to style meter element */
meter {
    -webkit-appearance: revert;
    appearance: revert;
}

/* preformatted text - use only for this feature */
:where(pre) {
    all: revert;
}

/* reset default text opacity of input placeholder */
::placeholder {
    color: unset;
}

/* remove default dot (•) sign */
::marker {
    content: initial;
}

/* fix the feature of 'hidden' attribute.
   display:revert; revert to element instead of attribute */
:where([hidden]) {
    display: none;
}

/* revert for bug in Chromium browsers
   - fix for the content editable attribute will work properly.
   - webkit-user-select: auto; added for Safari in case of using user-select:none on wrapper element*/
:where([contenteditable]:not([contenteditable="false"])) {
    -moz-user-modify: read-write;
    -webkit-user-modify: read-write;
    overflow-wrap: break-word;
    -webkit-line-break: after-white-space;
    -webkit-user-select: auto;
}

/* apply back the draggable feature - exist only in Chromium and Safari */
:where([draggable="true"]) {
    -webkit-user-drag: element;
}

/* Revert Modal native behavior */
:where(dialog:modal) {
    all: revert;
}

在 main.ts 文件中引入

1
import '@/assets/styles/reset.scss'

设置 scss 全局变量 新建文件 /src/assets/styles/variables.scss

1
2
3
4
5
$whiteColor: #fff;
$blackColor: #000;
$redColor: red;
$borderColor: #f5f5f5;
$backgroundColor: #eff0f1;

————————————————

配置 vite.config.ts 文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// vite.config.ts
export default ({ command, mode }: ConfigEnv): UserConfig => {
  return {
    css: {
      // 使用 scss 全局变量
      preprocessorOptions: {
        scss: {
          additionalData: '@import "src/assets/styles/variables.scss";'
        }
      }
    },
    plugins: [
      ...
    ],
  }
}

使用全局变量

1
2
3
4
5
6
7
8
9
<template>
  <h1 class="title">首页</h1>
</template>

<style scoped lang="scss">
  .title {
    color: $redColor;
  }
</style>

参考文档: 链接:https://juejin.cn/post/7135249540227006501

https://blog.csdn.net/lhz_333/article/details/125367315

https://juejin.cn/post/7174332521306390535

Licensed under CC BY-NC-SA 4.0
最后更新于 Sep 10, 2025 02:16 UTC
comments powered by Disqus
Built with Hugo
主题 StackJimmy 设计
Caret Up