vite搭建vue3项目完整版

vite搭建random项目

我们的项目叫做random vite官网,写本篇文章,主要是在封装组件库的时候,需要新建项目,所以结合工作中一个完整的项目搭建,记录一下这个过程,如果错误希望大家指正!大家搭建项目的过程中遇到了问题,也可以留言!

vite可以快速搭建一个项目,也可以一步一步配置,为了学习我们主要记录普通搭建

快速搭建

sql 复制代码
yarn create vite
project name: 项目名称
select a framework: 选择框架
select a variant: 选择是否使用ts, Customize with create-vue
Add TypeScript: 添加ts yes
Add JSX Support: 添加jsx支持 yes
Add Vue Router for Single Page Application development:添加router yes
Add Pinia for state management? 添加pinia管理数据? yes
Add Vitest for Unit Testing? 利用vitest做单元测试 no
Add an End-to-End Testing Solution? 集成端对端测试 no
Add ESLint for code quality? 添加eslint yes
Add Prettier for code formatting? 添加格式化代码 no

这样就可以类似vue cli快速生成一个项目,其中.eslintrc.cjs文件使用引入eslint

普通搭建

sql 复制代码
yarn create vite
√ Project name: ... 您的项目名称 xxx
√ Select a framework: >> 框架语言 Vue
√ Select a variant: >> 选择变体 TypeScript

下面我们使用普通搭建

补充src文件夹

vite基础配置

使用yarn dev启动项目但是项目没有在浏览器打开,所以需要在package.json中进行配置

perl 复制代码
"scripts": {
    // "dev": "vite --open --port 3000 --host local.bthome.com",
    // --open 是自动打开浏览器,--port 3000是设置端口号,--host 设置域名
    // 这些配置都可以在vite.config.ts中的serve中配置
    "dev": "vite", // 本地跑哪个dev环境vite -mode development
    "start:staging": "vite --mode staging",
    "build": "vue-tsc && vite build",
    "preview": "vite preview",
    // 根据不同环境打包,后面还需要配置环境变量
    "build:dev": "vite build --mode development",
    "build:staging": "vite build --mode staging",
    "build:uat": "vite build --mode uat",
    "build:prd": "vite build --mode production"
},

vite.config.ts配置

php 复制代码
import { defineConfig  } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  server: {
    // proxy: { // 本地开发环境通过代理实现跨域
    //   '/api': {
    //     target: 'xxxxxxxx', // 后端服务实际地址
    //     changeOrigin: true,
    //     rewrite: path => path.replace(/^/api/, '')
    //   }
    // }
    // https: true,
    open: true,
    port: 3000,
    // host: 'xxx.xxx.com'
  }
})

import { resolve } from 'path'报错

  1. 只需要安装@types/node 参考
sql 复制代码
yarn add @types/node -D
  1. 并且在vite.config.ts中配置,解决运行时找不到@报错
php 复制代码
import { defineConfig  } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  + resolve: {
  +  alias: {
  +    '@': resolve(__dirname, 'src')
  +  }
  + }
  server: {
    // proxy: { // 本地开发环境通过代理实现跨域
    //   '/api': {
    //     target: 'xxxxxxxx', // 后端服务实际地址
    //     changeOrigin: true,
    //     rewrite: path => path.replace(/^/api/, '')
    //   }
    // }
    // https: true,
    open: true,
    port: 3000,
    // host: 'xxx.xxx.com'
  }
})

引入eslint

ESLint官网 ESLint通关小册

你可以使用该命令安装并配置 ESLint:

kotlin 复制代码
npm init @eslint/config
vbnet 复制代码
? How would you like to use ESLint? ... 使用eslint的方式
  To check syntax only
  To check syntax and find problems
> To check syntax, find problems, and enforce code style 检查语法,发现问题,并且格式化代码样式
​
? What type of modules does your project use? ... 项目使用那种模块化引入方式
> JavaScript modules (import/export)
  CommonJS (require/exports)
  
? Which framework does your project use? ... 使用那种框架
  React
> Vue.js
  None of these
  
? Does your project use TypeScript? >> No / Yes 是否使用 TypeScript yes
​
Where does your code run? ...  (Press <space> to select, <a> to toggle all, <i> to invert selection)代码运行在浏览器端和Node.js端
√ Browser
√ Node
​
? How would you like to define a style for your project? ...给项目添加一种规范
  Use a popular style guide 使用流行风格指南
> Answer questions about your style 设置自己的风格
​
? What format do you want your config file to be in? ... 选择什么文件配置
> JavaScript
  YAML
  JSON
  
? What style of indentation do you use? ... 使用什么方式缩进
> Tabs
  Spaces
  
? What quotes do you use for strings? ... 字符串使用哪些引号
  Double
> Single
​
? What line endings do you use? ... 操作系统(这个配置可以不需要,随便选一个)
  Unix
> Windows
​
? Do you require semicolons? >> No / Yes 每行代码结尾是否校验加分号No
​
? Would you like to install them now? >> No / Yes 是否现在安装依赖
​
? Which package manager do you want to use? ... 使用哪种工具管理package 根据个人喜好
  npm
> yarn
  pnpm

在运行 npm init @eslint/config 后,你的目录下会有 .eslintrc.{js,yml,json} 文件。在里面你可以看到类似于这样的一些已经配置好了的规则:

json 复制代码
{
    "rules": {
        "semi": ["error", "always"],
        "quotes": ["error", "double"]
    }
}

"semi""quotes" 是 ESLint 规则的名称。第一个值代表规则的错误级别,有以下几种可供选择:

  • "off"0 - 关闭该规则
  • "warn"1 - 启用并警告(不影响现有代码)
  • "error"2 - 启用并报错(错误代码 1)

你可以调节这三档错误级别以精准控制 ESLint 规则实施方式(更多配置项和细节,参见配置文档)。

你的 .eslintrc.{js,yml,json} 配置文件也会包括这一行:

json 复制代码
{
    "extends": "eslint:recommended"
}

这一行将启用所有标记为"推荐"的规则。另外,你也可以通过在 npmjs.com 上搜索"eslint-config"并使用别人创建的配置。在没有使用别人的可共享配置或在配置中明确启用规则时,ESLint 不会检查你的代码。

提供一套我使用的.eslintrc.js的文件

arduino 复制代码
// https://eslint.org/docs/rules/
​
const isProduction = process.env.NODE_ENV === 'production'
​
module.exports = {
  root: true,
  env: {
    node: true,
    'vue/setup-compiler-macros': true,
  },
  extends: [
    'plugin:vue/vue3-essential',
    'eslint:recommended',
    '@vue/typescript/recommended',
  ],
  parserOptions: {
    ecmaVersion: 2020,
  },
  rules: {
    'curly': ['error', 'multi-line'],
    'eqeqeq': ['error', 'always'],
    'semi': ['error', 'never'],
    'indent': ['error', 2, {
      'SwitchCase': 1,
    }],
    'quotes': ['error', 'single', {
      'avoidEscape': true,
      'allowTemplateLiterals': true,
    }],
    'key-spacing': ['error', {
      'beforeColon': false,
      'afterColon': true,
      'mode': 'strict',
    }],
    'no-empty': 'error',
    'no-else-return': 'error',
    'no-multi-spaces': 'error',
    'require-await': 'error',
    'brace-style': ['error', 'stroustrup'],
    'spaced-comment': ['error', 'always'],
    'arrow-spacing': 'error',
    'no-duplicate-imports': 'error',
    'comma-spacing': ['error', {
      'before': false,
      'after': true,
    }],
    'default-case': 'error',
    'consistent-this': ['error', '_this'],
    'max-depth': ['error', 6],
    'max-lines': ['error', 800],
    'no-multi-str': 'error',
    'space-infix-ops': 'error',
    'space-before-blocks': ['error', 'always'],
    'space-before-function-paren': ['error', {
      'named': 'never',
      'anonymous': 'never',
      'asyncArrow': 'always',
    }],
    'keyword-spacing': ['error'],
    'prefer-const': 'error',
    'no-useless-return': 'error',
    'array-bracket-spacing': 'error',
    'no-useless-escape': 'off',
    'no-unused-vars': 'off',
    'no-eval': 'error',
    'no-var': 'error',
    'no-with': 'error',
    'no-alert': isProduction ? 'error' : 'warn',
    'no-console': isProduction ? 'error' : 'warn',
    'no-debugger': isProduction ? 'error' : 'warn',
    '@typescript-eslint/explicit-module-boundary-types': 'off',
    '@typescript-eslint/ban-types': ['error', {
      'extendDefaults': true,
      'types': {
        '{}': false,
      },
    }],
    '@typescript-eslint/no-unused-vars': 'off',
    '@typescript-eslint/no-non-null-assertion': 'off',
    'vue/multi-word-component-names': 'off',
    'vue/no-reserved-component-names': 'off',
  },
  overrides: [
    {
      files: [
        '**/__tests__/*.{j,t}s?(x)',
        '**/tests/unit/**/*.spec.{j,t}s?(x)'
      ],
      env: {
        jest: true,
      },
    },
  ],
}

如果eslint不管用请下载下面几个插件

perl 复制代码
"@typescript-eslint/eslint-plugin": "^6.4.0",
"@typescript-eslint/parser": "^6.4.0",
"eslint": "^8.47.0",
"eslint-plugin-vue": "^9.17.0",
"@vue/eslint-config-typescript": "^11.0.3",
"@rushstack/eslint-patch": "^1.3.2",

ESLint 支持多种格式的配置文件:

  • JavaScript - 使用.eslintrc.js和导出包含您的配置的对象。
  • JavaScript (ESM) -.eslintrc.cjs在 JavaScript 包中运行 ESLint 时使用,这些包"type":"module"package.json。请注意,ESLint 目前不支持 ESM 配置。
  • YAML - 使用.eslintrc.yamlor.eslintrc.yml来定义配置结构。
  • JSON - 用于.eslintrc.json定义配置结构。ESLint 的 JSON 文件也允许 JavaScript 样式的注释。
  • package.json - 在你的package.json文件中创建一个eslintConfig属性,并在那里定义你的配置。

如果同一目录下有多个配置文件,ESLint 只会使用一个。优先顺序如下:

  1. .eslintrc.js
  2. .eslintrc.cjs
  3. .eslintrc.yaml
  4. .eslintrc.yml
  5. .eslintrc.json
  6. package.json

加入样式(styles)

下载sasssass-loader的作用是sass转换成css, -D的作用是开发环境要用

csharp 复制代码
yarn add sass sass-loader  -D

思路:

  1. var变量主题样式

  2. 混入样式mixin

  3. 全局配置scss(variable mixin

  4. 全局样式

    1. 初始化样式
    2. 基础全局样式

variable变量主题样式

src目录下面新建assets文件夹 => styles文件,并在文件夹下新建variable.scss,文件内容如下

css 复制代码
$themeColor: #FE7100;
$themeHoverColor: #FE9B4C;
$themeActiveColor: #FE7100;
$textColor: #41464b;
$borderColor: #eee;
$lightGray: #f9f9f9;
​
$boxShadow: 3px 3px 3px rgba(#000, 0.15);
​
$transitionDelay: .2s;
$transitionDelayFast: .1s;
$transitionDelaySlow: .3s;
​
$borderRadius: 2px;
​
$padding-big: 16px;
$padding-base: 8px;
$padding-sm: 4px;
$margin-md: 12px;
$margin-base: 8px;
$margin-sm: 4px;
$size-base: 16px;
$size-md: 20px;
$h: 40px;
$h-sm: 24px;
$h-md: 32px;
$h-tip: 16px;

混入样式mixin

styles文件下新建mixin.scss,文件内容如下

less 复制代码
@mixin ellipsis-oneline() {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
​
@mixin ellipsis-multiline($line: 2) {
  word-wrap: break-word;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: $line;
  -webkit-box-orient: vertical;
}
​
@mixin flex-grid-layout() {
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
}
​
@mixin flex-grid-layout-children($col, $colWidth) {
  width: $colWidth;
  margin-bottom: calc(#{100 - $col * $colWidth} / #{$col - 1});
​
  &:not(:nth-child(#{$col}n)) {
    margin-right: calc(#{100 - $col * $colWidth} / #{$col - 1});
  }
}
​
@mixin overflow-overlay() {
  overflow: auto;
  overflow: overlay;
}
​
@mixin absolute-0 {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

混入样式如何使用?

less 复制代码
设置默认值
@mixin demo1($width: 10px) {
  width: $width;
}
@mixin demo2() {
  width: $width;
}
.link {
  max-width: 300px;
  margin-right: 20px;
  word-break: keep-all;
  white-space: nowrap;
  @include demo1(20px);  
  @include demo2();
}

全局配置scss

.vue组件中不能使用variable.scss中的变量,需要在vite.config.ts中添加配置,下面包含了scssless的配置

css 复制代码
css: {
    preprocessorOptions: {
      scss: {
        additionalData: `
          @import "@/assets/styles/variable.scss";
          @import "@/assets/styles/mixin.scss";
        `,
      },
      // less: {
      //   modifyVars: {
      //     hack: `true; @import (reference) "${resolve('/src/assets/styles/variable.less')}";`,
      //   },
      //   javascriptEnabled: true,
      // }
    },
}

全局样式

styles文件下新建global.scss,文件内容如下

css 复制代码
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  vertical-align: baseline;
  box-sizing: border-box;
}
​
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
  display: block;
}
​
body {
  line-height: 1;
  font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
}
​
html,
body {
  width: 100% !important;
  height: 100%;
  overflow: hidden;
  background-color: #fff;
  color: $textColor;
}
​
ol,
ul {
  list-style: none;
}
​
blockquote, q {
  quotes: none;
}
​
blockquote::before,
blockquote::after,
q::before,
q::after {
  content: '';
}
​
table {
  border-collapse: collapse;
  border-spacing: 0;
}
​
a {
  text-decoration: none;
}
​
::-webkit-scrollbar-thumb {
  background-color: #c1c1c1;
}
​
/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
::-webkit-scrollbar {
  width: 6px;
  height: 6px;
  /* border-radius: 6px; */
  background-color: transparent;
}
​
/*定义滚动条轨道 内阴影+圆角*/
::-webkit-scrollbar-track {
  /* -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); */
  /* border-radius: 6px; */
  background-color: transparent;
}
​
/*定义滑块 内阴影+圆角*/
::-webkit-scrollbar-thumb {
  border-radius: 6px;
  /* -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3); */
  /* background-color: #555; */
  background-color: hsla(220, 4%, 58%, 0.3);
}
​

main.ts中引入文件

arduino 复制代码
import '@/assets/styles/global.scss'

加入路由(router)

路由官网

sql 复制代码
yarn add vue-router@4

新建router文件 -> index.ts文件和modules文件夹

modules文件夹内容新建demos.ts

javascript 复制代码
import Demo from '@/views/home/Demo.vue'
const chartsRouter = {
  path: '/demos',
  component: Demo,
  name: 'demos',
  meta: {
    title: 'demos',
    icon: 'demos'
  }
}
​
export default chartsRouter

index.ts内容

javascript 复制代码
import { createRouter, createWebHashHistory} from 'vue-router'
import Home from '@/views/home/Home.vue'
import Demos from './modules/demos'
const routes = [
  {
    path: '/',
    name: 'home',
    component: Home
  },
  {
    path: '/about',
    name: 'about',
    component: () => import('@/views/home/About.vue')
  },
  Demos
]
const router = createRouter({
  history: createWebHashHistory(),
  routes
})
export default router

如果项目中出现这种报错

那就在tsconfig.json中添加代码

json 复制代码
{
  "compilerOptions": {
    "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,
​
     /* 解决找不到模块 */
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

main.ts中引入router

javascript 复制代码
import { createApp } from 'vue'
import App from './App.vue'
import '@/assets/styles/global.scss'
import router from './router'
​
const app = createApp(App)
app.use(router)
app.mount('#app')

App.vue写出口

xml 复制代码
<script setup lang="ts">
import { RouterView } from 'vue-router'
</script>
<template>
  <RouterView></RouterView>
</template>

可不可以不引入vue-router自动导入RouterView和自动导入vuerefreactive等 ?

自动导入ref,reactive等

arduino 复制代码
npm i -D unplugin-auto-import
yarn add unplugin-auto-import -D

vite.config.ts中配置vite

php 复制代码
// vite.config.js
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
​
export default defineConfig({
  plugins: [
    vue(),
    AutoImport({
      imports: ['vue', 'vue-router'], // 可以添加'pina', 'vue-i18n'等
      // 可以选择auto-import.d.ts生成的位置,使用ts建议设置为'src/auto-import.d.ts'
      dts: 'src/auto-import.d.ts'
    })
  ]
})

那么我们的App.vue就可以删除import { RouterView } from 'vue-router'

xml 复制代码
<script setup lang="ts">
</script>
<template>
  <RouterView></RouterView>
</template>

name的说明

我们打开vue开发者工具发现,组件的name就是组件的名称,vue3新语法无法给组件添加名字,如果不添加会默认把文件的名字作为组件名,怎么办?

参考

(1)安装

arduino 复制代码
yarn add vite-plugin-vue-setup-extend -D

(2)配置 vite.config.js中

javascript 复制代码
import vueSetupExtend from 'vite-plugin-vue-setup-extend'
​
export default defineConfig({
  plugins: [vue(), vueSetupExtend()],
})

在组件中使用

xml 复制代码
template>
  <div>hello world {{ a }}</div>
</template>
​
<script lang="ts" setup name="App">
  const a = 1 // 没有这个不生效
</script>

或者写两个script(不推荐)

xml 复制代码
<script lang="ts" setup>
</script>
<script>
export default {
  name: 'Home'
}
</script>
<template>
  <div class="home">Home</div>
</template>
<style lang="scss" scoped>
</style>

环境变量

掘金参考 vue-cli参考 vite参考环境变量是当前执行环境并影响进程执行行为的变量

文件新建和使用

项目根目录下面新建四个文件,在指定模式下加载

.env.production.env.staging.env.uat.env.development

.env.development为例子,其它三个参照

ini 复制代码
# just a flag
NODE_ENV = 'development'
# base api
VITE_APP_BASE_API = 'https://www.development.com'

注意:为了防止意外地将一些环境变量泄漏到客户端,只有以 VITE_ 为前缀的变量才会暴露给经过 vite 处理的代码

例如下面这些环境变量:

ini 复制代码
VITE_APP_BASE_API = 'https://www.development.com'
DB_PASSWORD=foobar

只有 VITE_SOME_KEY 会被暴露为 import.meta.env.VITE_SOME_KEY 提供给客户端源码,而 DB_PASSWORD 则不会。

arduino 复制代码
console.log(import.meta.env.VITE_APP_BASE_API) // 'https://www.development.com'
console.log(import.meta.env.DB_PASSWORD) // undefined

但是使用process.env.NODE_ENV是可以获取的

TypeScript 的智能提示

默认情况下,Vite 在 vite/client.d.ts 中为 import.meta.env 提供了类型定义。随着在 .env[mode] 文件中自定义了越来越多的环境变量,你可能想要在代码中获取这些以 VITE_ 为前缀的用户自定义环境变量的 TypeScript 智能提示。

要想做到这一点,你可以在 src 目录下创建一个 env.d.ts 文件,接着按下面这样增加 ImportMetaEnv 的定义:

csharp 复制代码
// / <reference types="vite/client" />
​
interface ImportMetaEnv {
  readonly VITE_APP_BASE_API: string
  // 更多环境变量...
}
​
interface ImportMeta {
  readonly env: ImportMetaEnv
}

本地服务使用哪个环境需要再package.json文件的scripts配置

json 复制代码
{
  "scripts": {
    "start": "vite --mode development",
    "start:dev": "vite --mode development",
    "start:staging": "vite --mode staging",
    "preview": "vite preview",
    "build:dev": "vite build --mode development",
    "build:test": "vite build --mode staging",
    "build:uat": "vite build --mode uat",
    "build:prd": "vite build --mode production",
    "build": "vue-tsc && vite build",
  }
}

HTML 环境变量替换(注意是HTML文件)

Vite 还支持在 HTML 文件中替换环境变量。import.meta.env 中的任何属性都可以通过特殊的 %ENV_NAME% 语法在 HTML 文件中使用:

css 复制代码
<h1>Vite is running in %MODE%</h1>
<p>Using data from %VITE_API_URL%</p>

如果环境变量在 import.meta.env 中不存在,比如不存在的 %NON_EXISTENT%,则会将被忽略而不被替换,这与 JS 中的 import.meta.env.NON_EXISTENT 不同,JS 中会被替换为 undefined

加入pinia(stores)

pinia官网

本期作为开发组件库前的准备,暂未使用到pinia

引入axios(api)

axios官网

下载

csharp 复制代码
yarn add axios
复制代码
npm install axios

utils文件下面新建request.ts配置允许携带cookie,全局添加Loading,以及报错

javascript 复制代码
import axios from 'axios'
// 这里以vant为例子,大家根据自己的ui组件库照着做即可
import { showSuccessToast, showFailToast, showLoadingToast, closeToast } from 'vant';
​
const instance = axios.create({
  baseURL: 'https://www.xxx.com',
  timeout: 5000,
  withCredentials: true // 带着cookies
})
​
// 添加请求拦截器
instance.interceptors.request.use(
  function (config) {
    showLoadingToast({
      message: 'Loading...',
      forbidClick: true,
    })
    // 在发送请求之前做些什么
    let { method, url = '' } = config
    // 这个是加一个时间戳,根据个人需求添加,一般不需要
    if (method?.toUpperCase() === 'GET') {
      url += url?.indexOf('?') !== -1 ? '&' : '?'
      config.url = `${url}b${+new Date()}=1`
    }
    return config
  },
  function (error) {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)
// 添加响应拦截器
instance.interceptors.response.use(
  function (response) {
    closeToast()
    return response.data
  },
  function (error) {
    // 对响应错误做点什么
    if (!error.response) {
      showFailToast('网络异常,请稍后重置')
    } else {
      showSuccessToast(error?.response?.data?.message)
    }
    return Promise.reject(error)
  }
)
​
export default instance

request,在src下面新建api,index.ts,

javascript 复制代码
import http from '@/utils/request'
export function searchArea(parentId: string) {
  return http.get(`/api/area/listByPId?parentId=${parentId}`)
}

.vue文件在哪里发请求

dart 复制代码
onMounted(async () => {
  const res = await searchArea('0')
})

axiso全局loading的控制

全局都加了loading,那么某些接口我不想loading怎么办?

  1. request.ts文件中扩展config

    typescript 复制代码
    import axios from 'axios'
    ​
    // 扩展config
    declare module "axios" {
      export interface AxiosRequestConfig {
        showLoading?: boolean
      }
    }
    const instance = axios.create({
        ...
    })
    ​
    // 添加请求拦截器
    instance.interceptors.request.use(
        ...
    )
    // 添加响应拦截器
    instance.interceptors.response.use(
        ...
    )
    ​
    export default instance
  2. 请求添加参数

    php 复制代码
    export const reqHouseList = (params: HouseListParams) => {
      return http({
        method: "GET",
        url: '/rivan/api/content/house/list',
        params,
        showLoading: false
      })
    }

引入vant

下载

csharp 复制代码
yarn add vant

引入组件main.ts

javascript 复制代码
import { createApp } from 'vue';
// 1. 引入你需要的组件
import vant from 'vant'
// 2. 引入组件样式
import 'vant/lib/index.css';
​
const app = createApp();
​
// 3. 注册你需要的组件
app.use(vant);

REM 适配

因为这个项目是移动端,所以,它需要去适配不同的手机屏幕。我们希望实现适配的效果是:与屏幕大小相关。

以按钮为例:在大屏手机,按钮的宽高都大些,在小屏手机上尺寸小些

Vant 中的样式默认使用px作为单位,如果需要使用rem单位,官方推荐使用以下两个工具,来达到目标。

  • postcss-pxtorem 是一款 postcss 插件,用于将单位转化为 rem (你写 px, 它帮你转 rem)
  • lib-flexible 用于设置 rem 基准值 (它帮你动态的设置 html font-size基准值)

官方推荐方案: rem 布局 youzan.github.io/vant/#/zh-C...

1 安装包

csharp 复制代码
// 作用:把px单位自动转成rem单位
yarn add postcss-pxtorem -D
​
// 修改rem基准值的js插件   需要在打包后需要使用
// 作用: 根据设置屏幕的宽度去调整rem的值(html标签上font-size的大小)
//       它的默认计算方式是屏幕宽度的1/10,默认值是37.5
yarn add amfe-flexible

2 vite.config.ts 配置 postcss 插件 (37.5 计算方式 => 屏幕宽度 / 10) 设计图对应的标准屏, 其他屏幕会自适应缩放的

php 复制代码
import { defineConfig  } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
+ import postCssPxToRem from 'postcss-pxtorem'
// setup name
import vueSetupExtend from 'vite-plugin-vue-setup-extend'
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(), vueSetupExtend()],
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src')
    }
  },
  css: {
    postcss: {
      plugins: [
        postCssPxToRem({
          rootValue: 37.5,
          propList: ['*']
        })
      ]
    }
  },
  server: {
    // proxy: { // 本地开发环境通过代理实现跨域
    //   '/api': {
    //     target: 'xxxxxxxx', // 后端服务实际地址
    //     changeOrigin: true,
    //     rewrite: path => path.replace(/^/api/, '')
    //   }
    // }
    https: true,
    open: true,
    port: 443,
    host: 'xxx.xxx.com'
  }
})

3 main.ts中加入

arduino 复制代码
import 'amfe-flexible'

修改vant主题色

目的:修改组件中所有的主题样式

vant官网 介绍里面社区生态里有个vant-themegitHub),进入基础组件,设置主题色后,点击右上角的下载主题,

得到三个文件,

variables.css引入到项目中去全局配置scss

variables.css文件内容

css 复制代码
:root:root {
  --van-black: #000;
  --van-white: #fff;
  --van-gray-1: #f7f8fa;
  --van-gray-2: #f2f3f5;
  --van-gray-3: #ebedf0;
  --van-gray-4: #dcdee0;
  --van-gray-5: #c8c9cc;
  --van-gray-6: #969799;
  --van-gray-7: #646566;
  --van-gray-8: #323233;
  --van-red: #ee0a24;
  --van-blue: #1989fa;
  --van-orange: #ff976a;
  --van-orange-dark: #ed6a0c;
  --van-orange-light: #fffbe8;
  --van-green: #07c160;
  
  --van-gradient-red: linear-gradient(to right, #ff6034, #ee0a24);
  --van-gradient-orange: linear-gradient(to right, #ffd01e, #ff8917);
  
  --van-primary-color: var(--van-blue);
  --van-success-color: var(--van-green);
  --van-danger-color: var(--van-red);
  --van-warning-color: var(--van-orange);
  --van-text-color: var(--van-gray-8);
  --van-text-color-2: var(--van-gray-6);
  --van-text-color-3: var(--van-gray-5);
  --van-active-color: var(--van-gray-2);
  --van-active-opacity: 0.6;
  --van-disabled-opacity: 0.5;
  --van-background: var(--van-gray-1);
  --van-background-2: var(--van-white);
  
  --van-padding-base: 4px;
  --van-padding-xs: 8px;
  --van-padding-sm: 12px;
  --van-padding-md: 16px;
  --van-padding-lg: 24px;
  --van-padding-xl: 32px;
  
  --van-font-size-xs: 10px;
  --van-font-size-sm: 12px;
  --van-font-size-md: 14px;
  --van-font-size-lg: 16px;
  --van-font-bold: 600;
  --van-line-height-xs: 14px;
  --van-line-height-sm: 18px;
  --van-line-height-md: 20px;
  --van-line-height-lg: 22px;
  --van-base-font: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica,
    Segoe UI, Arial, Roboto, 'PingFang SC', 'miui', 'Hiragino Sans GB', 'Microsoft Yahei',
    sans-serif;
  --van-price-font: Avenir-Heavy, PingFang SC, Helvetica Neue, Arial, sans-serif;
  
  --van-duration-base: 0.3s;
  --van-duration-fast: 0.2s;
  --van-ease-out: ease-out;
  --van-ease-in: ease-in;
  
  --van-border-color: var(--van-gray-3);
  --van-border-width: 1px;
  --van-radius-sm: 2px;
  --van-radius-md: 4px;
  --van-radius-lg: 8px;
  --van-radius-max: 999px;
}

:root:root为什么写两个重复的root?

由于 vant 中的主题变量也是在 :root 下声明的,所以在有些情况下会由于优先级的问题无法成功覆盖。通过 :root:root 可以显式地让你所写内容的优先级更高一些,从而确保主题变量的成功覆盖

vConsole的使用

安装

复制代码
npm install vconsole
csharp 复制代码
yarn add vconsole

main.ts文件中添加

arduino 复制代码
import VConsole from 'vconsole';
​
const vConsole = new VConsole();
// or init with options
// const vConsole = new VConsole({ theme: 'dark' });
​
if (process.env.NODE_ENV !== 'production') {
 app.use(vConsole)
}
​
// remove it when you finish debugging
// vConsole.destroy();

其他

固定的公共方法utils、页面views、ts类型types、枚举值enums.gitignore忽略上传 Hooks文件hooks

相关推荐
风无雨31 分钟前
GO启动一个视频下载接口 前端可以边下边放
前端·golang·音视频
aha-凯心1 小时前
前端学习 vben 之 axios interceptors
前端·学习
熊出没1 小时前
Vue前端导出页面为PDF文件
前端·vue.js·pdf
VOLUN1 小时前
Vue3项目中优雅封装API基础接口:getBaseApi设计解析
前端·vue.js·api
用户99045017780092 小时前
告别广告干扰,体验极简 JSON 格式化——这款工具让你专注代码本身
前端
前端极客探险家2 小时前
告别卡顿与慢响应!现代 Web 应用性能优化:从前端渲染到后端算法的全面提速指南
前端·算法·性能优化
袁煦丞3 小时前
【局域网秒传神器】LocalSend:cpolar内网穿透实验室第418个成功挑战
前端·程序员·远程工作
江城开朗的豌豆3 小时前
Vuex数据突然消失?六招教你轻松找回来!
前端·javascript·vue.js
好奇心笔记3 小时前
ai写代码随机拉大的,所以我准备给AI出一个设计规范
前端·javascript
江城开朗的豌豆3 小时前
Vue状态管理进阶:数据到底是怎么"跑"的?
前端·javascript·vue.js