Vite 搭建 Vue3 項(xiàng)目

VueCli和Vite

構(gòu)建項(xiàng)目

  • VueCli
    Vue CLI 4.x 需要 Node.js v8.9 或更高版本 (推薦 v10 以上)

    npm install -g @vue/cli
    # OR
    yarn global add @vue/cli
    
    vue --version   查看vue-cli版本
    
    vue create [projectName]  通過vue-cli創(chuàng)建項(xiàng)目
    
    
  • Vite
    Vite 需要 Node.js 版本 14.18+站削,16+

    npm create vite@latest
    

Vite路由

配置路由

npm install vue-router@next -S 安裝到生產(chǎn)環(huán)境
or
npm install vue-router@4
or 
yarn add vue-router@4

src 新建 router/index.js

import { createRouter, createWebHistory } from 'vue-router'
// 還有 createWebHashHistory 和 createMemoryHistory

createRouter({
  history: createWebHistory(),
  routes: [],
})

映射路由财著、渲染組件

import { createRouter, createWebHistory } from 'vue-router'

const routes = [
  {
    path: '/home',
    name: 'Home',
    component: () => import('../views/Home/index.vue')
  }
]

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

export default router

新建src/views/Home/index.vue

<template>
  <div>這是Home組件</div>
</template>

src/App.vue 設(shè)置渲染區(qū)域

<script setup>
</script>

<template>
  <router-view></router-view>
</template>

<style scoped>
</style>

main.js 引入路由

import { createApp } from 'vue'
import App from './App.vue'
// 引入路由
import router from './router'

const app = createApp(App)
app.use(router).mount('#app')

Vite Vuex

安裝vuex

npm install vuex@next --S  安裝到生產(chǎn)環(huán)境
or
yarn add vuex

main.js 引入路由

import { createApp } from 'vue'
import App from './App.vue'
// 引入路由
import router from './router'

+  // 引入store
+  import store from './store'

const app = createApp(App)
-  app.use(router).mount('#app')
M  app.use(router).use(store).mount('#app')

新建store文件谴蔑,src/store/index.js

import { createStore } from 'vuex'

const store = createStore({
  state () {
    return { }
  },
 mutations: {},
 getters:{},
 actions:{},
 modules:{}
})

export default store

Vuex的基礎(chǔ)知識(shí)


數(shù)據(jù)主要存在State中

  • 組件直接調(diào)用Actions带兜,Actions再去調(diào)用Mutations,Mutations再去修改State
  • 或者組件直接調(diào)用Mutations,Mutations再去修改State
  • 要更改 state 必須通過 Mutations 去做更新

定義number,通過 Mutations 去更新,src/store/index.js

import { createStore } from 'vuex'

const store = createStore({
  state () {
    return {
+     number: 0
    }
  },
 mutations: {
+  UPDATE_NUMBER (state, value) {
+    state.number = value
+  }
 },
 getters:{},
 actions:{},
 modules:{}
})

export default store

使用mutations(commit): src/views/Home/index.vue

<template>
  <div>這是Home組件</div>
+ <div>這是Store的數(shù)據(jù):{{number}}</div>
</template>
+ <script setup>
+   import { computed } from 'vue'
+   import { useStore } from 'vuex'

+   const store = useStore()

+   setTimeout(() => {
+    store.commit('UPDATE_NUMBER',50)
+   }, 2000)
+   const number = computed(() => store.state.number)
+ </script>

Vuex的Actions

  • mutations 是同步的
  • actions 是異步的

src/store/index.js

import { createStore } from 'vuex'

const store = createStore({
  state () {
    return {
     number: 0
    }
  },
+ getters:{},
+ // 同步
 mutations: {
+ // store.commit('UPDATE_NUMBER',50)
  UPDATE_NUMBER (state, value) {
    state.number = value
  }
 },
- getters:{},
 // 異步
 actions:{
+ // store.dispatch("NUMBERACTION",200)  調(diào)用
+ // 方法一:
+ // NUMBERACTION(context,payload){
+ // context.commit('UPDATE_NUMBER',payload)
+ // console.log(111,context.state.number) // 想獲取state的數(shù)據(jù)
+ // }
+ // 方法二(拓展方式):
M NUMBERACTION({state,commit},payload){
M  commit('UPDATE_NUMBER',payload)
M  console.log(111,state.number) // 想獲取state的數(shù)據(jù)
M }
 },
 modules:{}
})

export default store

使用actions(dispatch): src/views/Home/index.vue

<template>
  <div>這是Home組件</div>
  <div>這是Store的數(shù)據(jù):{{number}}</div>
</template>
<script setup>
import { computed } from 'vue'
import { useStore } from 'vuex'
const store = useStore()

setTimeout(() => {
M // store.commit('UPDATE_NUMBER',50)
+ store.dispatch('NUMBERACTION',200)
}, 2000)
const number = computed(() => store.state.number)
</script>

Vuex的Actions異步 Promise

import { createStore } from 'vuex'

const store = createStore({
  state () {
    return {
     number: 0
    }
  },
getters:{},
// 同步
 mutations: {
  UPDATE_NUMBER (state, value) {
    state.number = value
  }
 },
 // 異步
 actions:{
  NUMBERACTION({state,commit},payload){
+  return new Promise((resolve,reject)=>{
    commit('UPDATE_NUMBER',payload)
    console.log(111,state.number) // 想獲取state的數(shù)據(jù)
+   resolve() // 成功回調(diào)
+   // reject()  // catch回調(diào)
+  })
  }
 },
 modules:{}
})

export default store

使用Promise:src/views/Home/index.vue

<template>
  <div>這是Home組件</div>
  <div>這是Store的數(shù)據(jù):{{number}}</div>
</template>
<script setup>
import { computed } from 'vue'
import { useStore } from 'vuex'

const store = useStore()

setTimeout(() => {
  // store.commit('UPDATE_NUMBER',50)
M  store.dispatch('NUMBERACTION',200).then(response => {
+    console.log(response)
+  }).catch((error)=>{
+    console.log(error)
+  })
}, 2000)
const number = computed(() => store.state.number)
</script>

Vuex的Getters 計(jì)算屬性

import { createStore } from 'vuex'

const store = createStore({
  state () {
    return {
     number: 0
    }
  },
+ // 可以做一些計(jì)算屬性斥难,最終返回的是最新的結(jié)果枝嘶,不會(huì)影響state里面數(shù)據(jù)
 getters:{
+  getNumber:(state) => {
+    return state.number + 10
+  }
 },
 // 同步
 mutations: {
  UPDATE_NUMBER (state, value) {
    state.number = value
  }
 },
 // 異步
 actions:{
  NUMBERACTION({state,commit},payload){
    return new Promise((resolve,reject)=>{
      commit('UPDATE_NUMBER',payload)
      console.log(111,state.number) // 想獲取state的數(shù)據(jù)
      resolve() // 成功回調(diào)
      // reject()  // catch回調(diào)
    })
  }
 },
 modules:{}
})

export default store

使用Vuex的Getters

  • src/views/Home/index.vue
<template>
  <div>這是Home組件</div>
  <div>這是Store的數(shù)據(jù):{{number}}</div>
</template>
<script setup>
import { computed } from 'vue'
import { useStore } from 'vuex'

const store = useStore()

setTimeout(() => {
  // store.commit('UPDATE_NUMBER',50)
M // store.dispatch('NUMBERACTION',200).then(response => {
M //   console.log(response)
M // }).catch((error)=>{
M //  console.log(error)
M // })
+  const result = store.getters['getNumber']
+  console.log('result',result)
}, 2000)
const number = computed(() => store.state.number)
</script>

Vuex的Modules模塊化
解決多業(yè)務(wù)模塊在做state存儲(chǔ)時(shí),字段命名沖突

  • 新建store/modules/文件夾哑诊,并新建文件a.js群扶,b.js:
a.js:
+ const state = {
+  name: 10
+ }
+ const getters = {}
+ const mutations = { 
+   UPDATE_NUMBER (state, value) {
+     state.number = value
+   }
+ }
+ const actions = {
+   NUMBERACTION (context, payload) {
+    return new Promise((resolve,reject)=>{
+      commit('UPDATE_NUMBER',payload)
+      console.log(111,state.number) // 想獲取state的數(shù)據(jù)
+      resolve(1000) // 成功回調(diào)
+      // reject(1000)  // catch回調(diào)
+    })
+   }
+ }

+ export default {
+   namespaced: true, // 命名空間
+   state,
+   getters,
+   mutations,
+   actions
+ }
b.js:
+ const state = {
+  name: 20
+ }
+ const getters = {}
+ const mutations = { }
+ const actions = { }

+ export default {
+   namespaced: true, // 命名空間
+   state,
+   getters,
+   mutations,
+   actions
+ }
  • 在store/index.js下導(dǎo)入a.js,b.js:
import { createStore } from 'vuex'

+ import A from "./modules/a"
+ import B from "./modules/b"

const store = createStore({
-   state () {
-     return {
-      number: 0
-     }
-   },
-  // 可以做一些計(jì)算屬性镀裤,最終返回的是最新的結(jié)果竞阐,不會(huì)影響state里面數(shù)據(jù)
-  getters:{
-   getNumber:(state) => {
-     return state.number + 10
-   }
-  },
-  // 同步
-  mutations: {
-   UPDATE_NUMBER (state, value) {
-     state.number = value
-   }
-  },
-  // 異步
-  actions:{
-   NUMBERACTION({state,commit},payload){
-     return new Promise((resolve,reject)=>{
-     commit('UPDATE_NUMBER',payload)
-     console.log(111,state.number) // 想獲取state的數(shù)據(jù)
-      resolve() // 成功回調(diào)
-      // reject()  // catch回調(diào)
-     })
-   }
-  },
 modules:{
+  A,
+  B
 }
})

export default store

使用modules:src/views/Home/index.vue

<template>
  <div>這是Home組件</div>
  <div>這是Store的數(shù)據(jù):{{number}}</div>
</template>
<script setup>
import { computed } from 'vue'
import { useStore } from 'vuex'

const store = useStore()

setTimeout(() => {
+  store.commit('A/UPDATE_NUMBER',50)
  // store.commit('UPDATE_NUMBER',50)
M  store.dispatch('A/NUMBERACTION',200).then(response => {
M    console.log(response)
M  }).catch((error)=>{
M   console.log(error)
M  })
M  // const result = store.getters['getNumber']
M  // console.log('result',result)
}, 2000)
const number = computed(() => store.state.number)
</script>

Vite 配置 stylus

安裝依賴

npm install -D stylus-loader stylus

新建stylus變量:src/assets/style/stylConfig.styl

+ $red = red

根目錄新建vite.config.js

+ import { defineConfig } from 'vite'
+ import vue from '@vitejs/plugin-vue'
+ import path from 'path'

+ // https://vitejs.dev/config/
+ export default defineConfig(({ command, mode }) => {
+  return {
+    plugins: [vue()],
+    css: {
+     preprocessorOptions: {
+      stylus: {
+         imports: [path.resolve(__dirname, 'src/assets/style/stylConfig.styl')]
+       }
+     }
+   },
+  }
+ })

使用stylus:src/views/Home/index.vue

<template>
M <div class="red-home">這是Home組件</div>
  <div>這是Store的數(shù)據(jù):{{number}}</div>
</template>
<script setup>
import { computed } from 'vue'
import { useStore } from 'vuex'

const store = useStore()

setTimeout(() => {
  store.commit('A/UPDATE_NUMBER',50)
  // store.commit('UPDATE_NUMBER',50)
  store.dispatch('A/NUMBERACTION',200).then(response => {
    console.log(response)
  }).catch((error)=>{
   console.log(error)
  })
  // const result = store.getters['getNumber']
  // console.log('result',result)
}, 2000)

const number = computed(() => store.state.number)
</script>

+ <style lang="stylus">
+ .red-home
+   color $red
+ </style>

Vite配置路徑別名

引入配置根目錄vite.config.js:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

// https://vitejs.dev/config/
export default defineConfig(({ command, mode }) => {
  return {
    plugins: [vue()],
    css: {
      preprocessorOptions: {
       stylus: {
         imports: [path.resolve(__dirname, 'src/assets/style/stylConfig.styl')]
        }
      }
     },
+    resolve: {
+      alias: {
+        '@': path.resolve(__dirname, 'src')
+      }
+    }
  }
})

Vite esLint

初始化esLint

// 安裝
npm install eslint -D

// 初始化配置
npx eslint --init
// to check syntax, find problems, and enforce code style
// JavaScript modules (import/export)
// Vue.js
// No Use TypeScript
// Browser Node
// Use a popular style guide
// Standard
// JavaScript
// install them now? Yes
// use npm
// 執(zhí)行完之后,會(huì)在根目錄生成 .eslintrc.cjs 文件

自動(dòng)生成的.eslintrc.cjs

+ module.exports = {
+   env: {
+     browser: true,
+     es2021: true,
+     node: true
+   },
+   extends: [
+     'standard',
+     'plugin:vue/vue3-essential'
+   ],
+   parserOptions: {
+     ecmaVersion: 'latest',
+     sourceType: 'module',
+     ecmaFeatyres: {
+       modules: true
+     },
+     requireConfigFile: false,
+     parser: '@babel/eslint-parser'
+   },
+   plugins: [
+     'vue'
+   ],
+   rules: {
+   }
+ }

自動(dòng)格式化esLint

// 安裝
npm install vite-plugin-eslint @babel/eslint-parser -D

配置vite.config.js文件

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
+ import eslintPlugin from 'vite-plugin-eslint'

// https://vitejs.dev/config/
export default defineConfig(({ command, mode }) => {
  return {
    plugins: [
      vue(),
+     // 添加下面這塊
+     eslintPlugin({
+       include: ['src/**/*.js', 'src/**/*.vue', 'src/*.js', 'src/*.vue']
+     })
    ],
    css: {
      preprocessorOptions: {
       stylus: {
         imports: [path.resolve(__dirname, 'src/assets/style/stylConfig.styl')]
        }
      }
     },
   resolve: {
     alias: {
       '@': path.resolve(__dirname, 'src')
     }
   }
  }
})

.eslintrc.cjs 添加規(guī)則

//  規(guī)則:http://eslint.cn/docs/rules/
+ module.exports = {
+   env: {
+     browser: true,
+     es2021: true,
+     node: true
+   },
+   extends: [
+     'standard',
+     'plugin:vue/vue3-essential'
+   ],
+   parserOptions: {
+     ecmaVersion: 'latest',
+     sourceType: 'module',
+     ecmaFeatyres: {
+       modules: true
+     },
+     requireConfigFile: false,
+     parser: '@babel/eslint-parser'
+   },
+   plugins: [
+     'vue'
+   ],
+   rules: {
+    semi: [2, 'never'], // 禁止尾部使用分號(hào)“;”
+    'no-var': 'error', // 禁止使用 var
+    indent: ['error', 2], // 縮進(jìn)2格
+    'no-mixed-spaces-and-tabs': 'error', // 不能空格與tab混用
+    quotes: [2, 'single'], // 使用單引號(hào)
+    'vue/html-closing-bracket-newline': 'off', // 不強(qiáng)制換行暑劝,
+    'vue/singleline-html-element-content-newline': 'off', // 不強(qiáng)制換行
+    'vue/multi-word-component-names': 'off',
+    'vue/max-attributes-per-line': ['error', {
+      singleline: { max: 5 },
+      multiline: { max: 5 }
+    }]
+   }
+ }

vscode配置:文件→首選項(xiàng)→設(shè)置→settings.json

{
+  "[vue]": {
+    "editor.defaultFormatter": "octref.vetur"
+  },
+  "eslint.options":{ // 指定vscode的eslint所處理的文件的后綴
+    "extensions":[
+      ".js",
+      ".vue",
+      ".ts",
+      ".tsx"
+    ]
+  },
+  // 自動(dòng)修復(fù)
+  "editor.codeActionsOnSave": {
+    "source.fixAll.eslint": true
+  }
}

Vite 配置跨域Proxy

本地環(huán)境跨域

server:{
  proxy:{
    '/api':{
      target: 'xxxxx', // 代理的目標(biāo)地址
      changeOrigin: true,
      secure: true, // 是否https接口
      ws: true, // 是否代理websockets
      rewrite: (path) => path.replace(/^\/api/,'')
    }
  }
}

初始化axios

// 安裝
npm install axios -S

刪減:src/views/Home/index.vue

<template>
  <div class="red-home">這是Home組件</div>
  <div>這是Store的數(shù)據(jù):{{number}}</div>
</template>
<script setup>
- import { computed } from 'vue'
- import { useStore } from 'vuex'

- const store = useStore()

- setTimeout(() => {
-   store.commit('A/UPDATE_NUMBER',50)
-   store.dispatch('A/NUMBERACTION',200).then(response => {
-    console.log(response)
-  }).catch((error)=>{
-   console.log(error)
-  })
- }, 2000)

- const number = computed(() => store.state.number)
</script>

<style lang="stylus">
 .red-home
   color $red
</style>

關(guān)于舊的全局掛在axios方式:

app.config.globalProperties
一個(gè)用于注冊(cè)能夠被應(yīng)用內(nèi)所有組件實(shí)例訪問到的全局屬性的對(duì)象骆莹。
這是對(duì) Vue 2 中 Vue.prototype 使用方式的一種替代,此寫法在 Vue 3 已經(jīng)不存在了担猛。
與任何全局的東西一樣幕垦,應(yīng)該謹(jǐn)慎使用。
由此可知傅联,vue3其實(shí)并不支持這種寫法先改,但是也可以用,這里只做知識(shí)拓展蒸走,不建議使用

main.js:
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

+ import axios from 'axios'

const app = createApp(App)
// 全局載入
+ app.config.globalProperties.$_api = axios
app.use(router).use(store).mount('#app')

--------------------------------

src/views/Home/index.vue:
<script setup>
+ import { getCurrentInstance } from 'vue'

+ const { proxy } = getCurrentInstance()

+ proxy.$axios.post('/xxx)
</script>

了解同源策略

/**
* 同源策略
* 1.http\https
* 2.端口
* 3.www.baidu.com\mail.163.com
*/

跨域重定向:配置vite.config.js文件

// https://cn.vitejs.dev/config/server-options.html#server-proxy
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import eslintPlugin from 'vite-plugin-eslint'

// https://vitejs.dev/config/
export default defineConfig(({ command, mode }) => {
  return {
    plugins: [
      vue(),
     // 添加下面這塊
     eslintPlugin({
       include: ['src/**/*.js', 'src/**/*.vue', 'src/*.js', 'src/*.vue']
     })
    ],
    css: {
      preprocessorOptions: {
       stylus: {
         imports: [path.resolve(__dirname, 'src/assets/style/stylConfig.styl')]
        }
      }
    },
    resolve: {
     alias: {
       '@': path.resolve(__dirname, 'src')
      }
    },
+   server: {
+     proxy: {
+       /**
+        * 1仇奶、匹配接口地址前面的字符是 /api,如果成功便會(huì)進(jìn)入重定向
+        * 2比驻、接口組合该溯,用target屬性的地址拼接請(qǐng)求地址
+        */
+       '/api': {
+         // 前兩個(gè)必填
+         target: 'http://xxx.cn',
+         changeOrigin: true,
+         // secure: true, // 是否https接口
+         // ws: true // 是否代理websockets
+         // rewrite: (path) => path.replace(/^\/api/, '')  // 匹配開頭為/api 替換為空
+       }
+     }
+   },
  }
})

Vite 配置環(huán)境變量

了解環(huán)境變量
開發(fā)項(xiàng)目時(shí)環(huán)境主要分為:
1、本地環(huán)境 == 在電腦開發(fā)項(xiàng)目
2别惦、開發(fā)環(huán)境 == 部署在服務(wù)器環(huán)境(可以是朗伶,公司內(nèi)部搭建的服務(wù))// 192.168.110.184:8000
3、測(cè)試環(huán)境 == 部署在服務(wù)器環(huán)境(可以是步咪,公司內(nèi)部搭建的服務(wù))// 192.168.110.184:8001
4论皆、生產(chǎn)環(huán)境 == 部署在服務(wù)器環(huán)境,已經(jīng)是對(duì)外公布的環(huán)境,可通過正式域名訪問的環(huán)境
5点晴、灰色環(huán)境 == 比較小型數(shù)據(jù)應(yīng)用(公司內(nèi)部測(cè)試感凤,也是屬于生產(chǎn)環(huán)境的一種)

參考文檔:Vite 官方中文文檔-環(huán)境變量和模式

Vite 在一個(gè)特殊的 import.meta.env對(duì)象上暴露環(huán)境變量:

// 通過內(nèi)建變量來判斷運(yùn)行環(huán)境
console.log('import.meta.env.MODE', import.meta.env.MODE)
console.log('import.meta.env.PROD', import.meta.env.PROD)
console.log('import.meta.env.DEV', import.meta.env.DEV)
console.log('import.meta.env.SSR', import.meta.env.SSR)

環(huán)境變量定義
.env文件:

運(yùn)行 npm run dev ,會(huì)自動(dòng)讀取 .env.development 文件
運(yùn)行 npm run build 粒督,會(huì)自動(dòng)讀取 .env.production 文件

tips:為了防止意外地將一些環(huán)境變量泄漏到客戶端陪竿,只有以VITE_為前綴的變量才會(huì)暴露給經(jīng)過 vite 處理的代碼:

VITE_SOME_KEY=123
DB_PASSWORD=foobar

只有VITE_SOME_KEY會(huì)被暴露為import.meta.env.VITE_SOME_KEY提供給客戶端源碼,而DB_PASSWORD則不會(huì)屠橄。

根目錄新建.env.development文件

+ VITE_API = http://xx.dev.cn

根目錄新建.env.production文件

+ VITE_API = http://xx.pro.cn

配置不同環(huán)境的變量
在某些情況下族跛,若想在vite build時(shí)運(yùn)行不同的模式來渲染不同的標(biāo)題,你可以通過傳遞--mode選項(xiàng)標(biāo)志來覆蓋命令使用的默認(rèn)模式锐墙。例如礁哄,如果你想在 staging (預(yù)發(fā)布)模式下構(gòu)建應(yīng)用:

vite build --mode staging

還需要新建一個(gè) .env.staging 文件:

# .env.staging
VITE_APP_TITLE=My App (staging)

模式
在某些情況下,若想在vite build時(shí)運(yùn)行不同的模式來渲染不同的標(biāo)題溪北,你可以通過傳遞--mode選項(xiàng)標(biāo)志來覆蓋命令使用的默認(rèn)模式桐绒。

1、本地環(huán)境  npm run dev
2之拨、開發(fā)環(huán)境  package.json: "build:dev" npm run build --mode dev
3茉继、測(cè)試環(huán)境  package.json: "build:test" npm run build --mode test
4、生產(chǎn)環(huán)境  npm run build 自動(dòng)讀取.env.production
5蚀乔、灰度環(huán)境

--mode dev 需要新建一個(gè) .env.dev 文件:

+ VITE_API = 192.168.110.184:8000

--mode test需要新建一個(gè) .env.test 文件:

+ VITE_API = 192.168.110.184:8001

在vite.config.js中應(yīng)用:

// https://cn.vitejs.dev/config/server-options.html#server-proxy
M import { defineConfig,loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import eslintPlugin from 'vite-plugin-eslint'

// https://vitejs.dev/config/
export default defineConfig(({ command, mode }) => {
+ // 根據(jù)當(dāng)前工作目錄中的 `mode` 加載 .env 文件
+ // 設(shè)置第三個(gè)參數(shù)為 '' 來加載所有環(huán)境變量烁竭,而不管是否有 `VITE_` 前綴。

+ // js ts 文件需要引入loadEnv
+ // .vue 文件直接用 import.meta.env.DEV

+ const env = loadEnv(mode, process.cwd(), '')
+ console.log('env', env)
  return {
    plugins: [
      vue(),
     // 添加下面這塊
     eslintPlugin({
       include: ['src/**/*.js', 'src/**/*.vue', 'src/*.js', 'src/*.vue']
     })
    ],
    css: {
      preprocessorOptions: {
       stylus: {
         imports: [path.resolve(__dirname, 'src/assets/style/stylConfig.styl')]
        }
      }
    },
    resolve: {
     alias: {
       '@': path.resolve(__dirname, 'src')
      }
    },
   server: {
     proxy: {
       /**
        * 1吉挣、匹配接口地址前面的字符是 /api颖变,如果成功便會(huì)進(jìn)入重定向
        * 2、接口組合听想,用target屬性的地址拼接請(qǐng)求地址
        */
       '/api': {
         // 前兩個(gè)必填
M        target: env.VITE_API, //  192.168.110.184:8000/8001
         changeOrigin: true,
         // secure: true, // 是否https接口
         // ws: true // 是否代理websockets
         // rewrite: (path) => path.replace(/^\/api/, '')  // 匹配開頭為/api 替換為空
       }
     }
   },
  }
})
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末腥刹,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子汉买,更是在濱河造成了極大的恐慌衔峰,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蛙粘,死亡現(xiàn)場(chǎng)離奇詭異垫卤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)出牧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門穴肘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人舔痕,你說我怎么就攤上這事评抚”海” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵慨代,是天一觀的道長(zhǎng)邢笙。 經(jīng)常有香客問我,道長(zhǎng)侍匙,這世上最難降的妖魔是什么氮惯? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮想暗,結(jié)果婚禮上妇汗,老公的妹妹穿的比我還像新娘。我一直安慰自己说莫,他們只是感情好杨箭,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著唬滑,像睡著了一般告唆。 火紅的嫁衣襯著肌膚如雪棺弊。 梳的紋絲不亂的頭發(fā)上晶密,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音模她,去河邊找鬼稻艰。 笑死,一個(gè)胖子當(dāng)著我的面吹牛侈净,可吹牛的內(nèi)容都是我干的尊勿。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼畜侦,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼元扔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起旋膳,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤澎语,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后验懊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體擅羞,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年义图,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了减俏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡碱工,死狀恐怖娃承,靈堂內(nèi)的尸體忽然破棺而出奏夫,到底是詐尸還是另有隱情,我是刑警寧澤草慧,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布桶蛔,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏恩沽。R本人自食惡果不足惜院刁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望碟婆。 院中可真熱鬧,春花似錦惕稻、人聲如沸竖共。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)公给。三九已至,卻和暖如春蜘渣,著一層夾襖步出監(jiān)牢的瞬間淌铐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工蔫缸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留腿准,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓拾碌,卻偏偏與公主長(zhǎng)得像吐葱,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子校翔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容