当前位置: 首页>后端>正文

vue3+Ant Design的项目搭建

  • 涓€銆佸熀纭€璇存槑
    - 鍙傝€冩枃妗?
  • 浜屻€侀」鐩粨鏋?/li>
  • 涓夈€佷娇鐢ㄨ剼鎵嬫灦鏋勫缓
  • 鍥涖€侀厤缃畍ite.config.js
  • 浜斻€佷娇鐢?store
  • 鍏€佷娇鐢?Ant Design
    • 浣跨敤鏃剁殑闂
      • 鎸夌収瀹樻柟鏂囨。璇存槑浣跨敤 message 鍑虹幇涓嶆樉绀虹殑闂澶勭悊
      • 鍔ㄦ€佸姞杞?Icon 鍥炬爣
  • 涓冦€丠TTP 璇锋眰鐨勫皝瑁?/li>
  • 鍏朵粬

涓€銆佸熀纭€璇存槑

  • 浣跨敤鎶€鏈細Vite3 + Vue3 + TypeScript + Ant Design + axios + Vue-Router

1.2 鍙傝€冩枃妗?/h4>
  • Vue3
  • Vue Router (Vue.js 鐨勫畼鏂硅矾鐢?
  • Ant Design (缁勪欢妗嗘灦)
  • Vite (鍓嶇鏋勫缓宸ュ叿)
  • Pinia (Vue 鐨勫瓨鍌ㄥ簱)
  • Axios (鍩轰簬 promise 缃戠粶璇锋眰搴?
  • TypeScript

浜屻€?椤圭洰缁撴瀯

practice-vue-project
.
鈹溾攢鈹€ index.html                # 椤甸潰鍏ュ彛
鈹溾攢鈹€ public                    # 璇ユ枃浠朵笅鐨勭洰褰曟墦鍖呮椂灏嗙洿鎺ユ嫹璐濆彧鏍圭洰褰?
鈹溾攢鈹€ src                       # 婧愮爜鏂囦欢
鈹?  鈹溾攢鈹€ assets                # 闈欐€佽祫婧?
鈹?  鈹?  鈹溾攢鈹€ base.css          # 鍏ㄥ眬鐨刢ss鍙橀噺
鈹?  鈹溾攢鈹€ constants             # 鍏ㄥ眬甯搁噺瀹氫箟
鈹?  鈹溾攢鈹€ components            # 鍏ㄥ眬缁勪欢
鈹?  鈹溾攢鈹€ hooks                 # 灏佽鐨勫父鐢╤ooks
鈹?  鈹溾攢鈹€ layouts               # 鍏叡甯冨眬
鈹?  鈹溾攢鈹€ pages                 # 椤甸潰缁勪欢锛堜笅闈㈠彧鍒椾妇涓昏鏂囦欢锛?
鈹?  鈹溾攢鈹€ router                # 璺敱閰嶇疆鏂囦欢
鈹?  鈹溾攢鈹€ service               # 鎺ュ彛璇锋眰鐩稿叧
鈹?  鈹?  鈹溾攢鈹€ index.ts          # 鏁村悎鎺ュ彛璇锋眰锛岀粺涓€瀵煎嚭
鈹?  鈹溾攢鈹€ typings               # 鍏ㄥ眬绫诲瀷澹版槑
鈹?  鈹溾攢鈹€ App.vue
鈹?  鈹溾攢鈹€ main.ts               # 鍒涘缓APP鎸傝浇
鈹?  鈹斺攢鈹€ utils                 # 宸ュ叿鍑芥暟
鈹?      鈹斺攢鈹€ request.ts        # 鍩轰簬axios灏佽鐨勮姹傜被
鈹溾攢鈹€ .env.dev                  # 寮€鍙戠幆澧冮厤缃枃浠?
鈹溾攢鈹€ .env.production           # 鐢熶骇鐜閰嶇疆鏂囦欢
鈹溾攢鈹€ .gitignore                # git璺熻釜蹇界暐閰嶇疆
鈹溾攢鈹€ env.d.ts                  # 鐜鍙橀噺绫诲瀷瀹氫箟
鈹溾攢鈹€ index.html                # 妯℃澘:鍖呭惈缃戦〉鏍囬鍥炬爣
鈹溾攢鈹€ tsconfig.json             # TS閰嶇疆鏂囦欢
鈹斺攢鈹€ vite.config.js            # vite 閰嶇疆鏂囦欢

涓夈€佷娇鐢ㄨ剼鎵嬫灦鏋勫缓

  • 浣跨敤鑴氭墜鏋跺垱寤烘柊椤圭洰锛?code>npm create vue@latest
  • 鏍规嵁闇€瑕侀€夋嫨闇€瑕佺殑鍔熻兘
  • 瀹夎渚濊禆锛?
     cd <your-project-name>
     npm install
    
  • 鍚姩椤圭洰锛?code>npm run dev

鍥涖€侀厤缃畍ite.config.js

  • 鑷姩瑙f瀽椤圭洰鏍圭洰褰曚笅 vite.config.js 鐨勯厤缃枃浠?/p>

  • 鍙湁浠?VITE_ 涓哄墠缂€鐨勫彉閲忔墠浼氭毚闇茬粰缁忚繃 vite 澶勭悊鐨勪唬鐮?/p>

  • 鑾峰彇鐜鍙橀噺鐨勬柟娉曪細import.meta.env.VITE_xxx

  • 闇€瑕佸湪 package.json 涓慨鏀硅繍琛岀殑鍛戒护锛屼繚璇?vite 鑾峰彇鐜鍙橀噺

  • 濡備笅涓虹ず渚嬬殑閰嶇疆锛岃鎯呭弬鑰冨畼鏂规枃妗?/p>

     // vite.config.js
    
      import { fileURLToPath, URL } from 'node:url'
    
      import { defineConfig, loadEnv } from 'vite'
      import vue from '@vitejs/plugin-vue'
      import vueJsx from '@vitejs/plugin-vue-jsx'
      import Components from 'unplugin-vue-components/vite'
      import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'
    
      // mode: dev鐢ㄤ簬寮€鍙戯紝production鐢ㄤ簬鏋勫缓锛屽彲浠ヤ娇鐢ㄥ懡浠よ--mode閲嶅啓
    
      // 椤圭洰閰嶇疆椤癸細榛樿涓嶅姞杞?.env 鏂囦欢
      export default defineConfig(({ mode }: { mode: string }) => {
        // 鏍规嵁褰撳墠宸ヤ綔鐩綍涓殑 `mode` 鍔犺浇 .env 鏂囦欢
        // 璁剧疆绗笁涓弬鏁颁负 '' 鏉ュ姞杞芥墍鏈夌幆澧冨彉閲忥紝鑰屼笉绠℃槸鍚︽湁 `VITE_` 鍓嶇紑銆?
        const env = loadEnv(mode, process.cwd(), '')
    
        return {
          base: env.VITE_APP_BASE || '/',
          // 闇€瑕佺敤鍒扮殑鎻掍欢鏁扮粍銆?
          plugins: [
            vue(),
            vueJsx(),
            Components({
              resolvers: [
                AntDesignVueResolver({
                  importStyle: false // css in js
                })
              ]
            })
          ],
          // 璺緞瑙f瀽
          resolve: {
            alias: {
              '@': fileURLToPath(new URL('./src', import.meta.url)),
              comps: fileURLToPath(new URL('./src/components', import.meta.url)),
              views: fileURLToPath(new URL('./src/views', import.meta.url))
            }
          },
          // 鏈嶅姟鍚姩鐨勭鍙g瓑
          server: {
            https: false,
            port: 5173,
            host: '0.0.0.0',
            // 寮€鍙戞湇鍔″櫒鍚姩鏃讹紝鑷姩鍦ㄦ祻瑙堝櫒涓墦寮€搴旂敤绋嬪簭
            open: false,
            // 璺ㄥ煙
            cors: false
          }
        }
      })
    
    
  • 淇敼榛樿鐨勫惎鍔ㄧ▼搴?/p>

    // package.json
      "scripts": {
           "dev": "vite --mode dev",
          //....
       }
    
  • 澧炲姞鐜鍙橀噺鐨勬枃浠?code>.env.dev鍜?code>.env.production

浜斻€佷娇鐢?store

  • 閰嶇疆

     // main.ts
    import { createPinia } from 'pinia'
    app.use(createPinia())
    
     // 閬垮厤鍒锋柊浠ュ悗锛宻tore涓㈠け锛岃繘琛屾暟鎹殑鎸佷箙鍖?
    // 馃憠 鎸佷箙鍖杙inia
    const store = useStore()
    // 椤甸潰杩涘叆锛氬悎骞剁姸鎬?
    const localState = localStorage.getItem(AiAppStorageKey)
    if (localState) {
      console.log('[娓╅Θ鎻愮ず]锛氬悎骞禨tore...')
      store.$state = JSON.parse(localState)
    }
    // 椤甸潰鍒锋柊锛氬瓨鍌ㄧ姸鎬?
    window.addEventListener('beforeunload', () => {
      console.log('[娓╅Θ鎻愮ず]锛氱紦瀛楽tore...')
      localStorage.setItem(AiAppStorageKey, JSON.stringify(store.$state))
    })
    
    
  • 瀹氫箟

    // store/index.ts
    import { defineStore } from 'pinia'
    import type { UserInfoType } from '@/typings'
    interface StoreProps {
      token: string
      userInfo: UserInfoType | any
    }
    
    interface ActionProps {
      setToken: (token: string) => void
      resetToken: () => void
    }
    // 鐢ㄤ簬淇濆瓨token
    export const useStore = defineStore<string, StoreProps, any, ActionProps>  ('appStore', {
      state: () => ({ token: '', userInfo: {} }),
      actions: {
        async setToken(token) {
          this.token = token
        },
        async resetToken() {
          this.token = ''
        }
      }
    })
    
    
  • 浣跨敤

    const store = useStore()
    store.setToken("娴嬭瘯")
    

鍏€佷娇鐢?Ant Design

  • 瀹夎渚濊禆

    # 瀹夎AntDesign锛?
    npm install ant-design-vue@4.x --save
    # 瀹夎antDesign Icon
    npm install --save @ant-design/icons-vue
    
  • 寮曞叆

    // 鏂囦欢锛歴rc\main.ts
    import Antd from 'ant-design-vue'
    import 'ant-design-vue/dist/reset.css'
    // 1. 鍒涘缓app
    const app = createApp(App)
    
    // 2.浣跨敤鎻掍欢Antd
    app.use(Antd)
    
    // 3. 鎸傚湪鍦╥d=app鐨勬牴
    app.mount('#app')
    

6.1 浣跨敤鏃剁殑闂

6.1.1 鎸夌収瀹樻柟鏂囨。璇存槑浣跨敤 message 鍑虹幇涓嶆樉绀虹殑闂澶勭悊

  • 浣跨敤缃戜笂鍚勭鏂规硶鍚庝粛鐒朵笉鏄剧ず
  • 鎸囨槑鎸傝浇鐨勮妭鐐?
     //  鏂囦欢锛歴rc\main.ts
      import { message } from 'ant-design-vue'
      message.config({
        maxCount: 1,
        getContainer: () => document.getElementById('message_modal') || document.body
    })
    
  • 鍦?app 鐨勮妭鐐瑰悓绾у鍔?id=message_modal 鐨勮妭鐐?/li>

6.1.2 鍔ㄦ€佸姞杞?Icon 鍥炬爣

  • 娉ㄥ唽 Icon 缁勪欢

     // 鏂囦欢锛歮ain.js
     import * as antIcons from '@ant-design/icons-vue'
     Object.keys(antIcons).forEach((key) => {
       app.component(key, antIcons[key as keyof typeof antIcons])
     })
     app.config.globalProperties.$antIcons = antIcons
    
  • 浣跨敤

    <script setup lang="ts">
    import { ref } from 'vue';
    const data = ref([{ "name": "a", "icon": "SettingOutlined" }])
    </script>
    
    <template>
      <template v-for="item in data">
        <component :is="item.icon">{{ item.name }}</component>
      </template>
    </template>
    

涓冦€丠TTP 璇锋眰鐨勫皝瑁?/h2>
// src\utils\request.ts
import axios from 'axios'
import type { AxiosInstance, AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'
import { useStore } from '@/store'
/********************
 ** 鍩虹绫诲瀷
 ********************/
export interface BaseResponse<T = any> {
  success: boolean
  errCode: number
  data: T
  errMessage: string
}

/********************
 ** 鍒涘缓axios瀹炰緥
 ********************/
const service: AxiosInstance = axios.create({
  baseURL: import.meta.env.VITE_APP_HOST,
  timeout: 500000
})

/********************
 ** 璇锋眰鎷︽埅鍣?
 ********************/
service.interceptors.request.use(
  (config: AxiosRequestConfig): any => {
    const store = useStore()
    // -- 閰嶇疆璇锋眰澶?
    const token = store.token
    config.headers = {
      'Content-Type': 'application/json',
      Authorization: token `Bearer ${token}` : ''
    }
    return config
  },
  (error: AxiosError) => Promise.reject(error)
)

/********************
 ** 鍝嶅簲鎷︽埅鍣?
 ********************/
service.interceptors.response.use(
  (response: AxiosResponse): any => {
    const { status } = response
    console.log(response)
    if (status === 200) {
      return response.data
    } else {
      return Promise.reject(new Error(response?.data?.errMessage ?'鏈煡閿欒'))
    }
  },
  (error: AxiosError) => {
    // 澶勭悊 HTTP 閿欒
    if (!error.response) {
      return Promise.reject({ code: 503, message: `缃戠粶杩炴帴澶辫触` })
    } else {
      const store = useStore()
      let errorMsg = {
        code: error.response?.status,
        message: (error.response?.data as BaseResponse).errMessage,
        response: error.response
      }
      if (errorMsg?.code === 401) {
        store.resetStore()
        errorMsg.message = '鏉冮檺杩囨湡锛岃閲嶆柊鐧诲綍'
      }
      return Promise.reject(errorMsg)
    }
  }
)

/********************
 ** 瀵煎嚭璇锋眰鏂规硶锛堥噸鐐癸級
 ********************/

export const http = {
  get<T = any>(
    url: string,
    params?: object,
    config?: AxiosRequestConfig
  ): Promise<BaseResponse<T>> {
    const conf = { params, ...config }
    return service.get(url, conf)
  },
  post<T = any>(url: string, data?: object, config?: AxiosRequestConfig): Promise<BaseResponse<T>> {
    return service.post(url, data, config)
  },

  put<T = any>(url: string, data?: object, config?: AxiosRequestConfig): Promise<BaseResponse<T>> {
    return service.put(url, data, config)
  },

  delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<BaseResponse<T>> {
    return service.delete(url, config)
  }
}

  • 浣跨敤
// src\service\users.ts
import { http } from '@/utils/request'

// 鐧诲綍
export function login(data: USERAPI.LoginParamType) {
  return http.post<string>('/ai-api/ai-auth/auth/login', data)
}

// 閫€鍑虹櫥褰?
export function logout() {
  return http.post<string>('/ai-api/ai-auth/auth/logout')
}

// 鑾峰彇鐢ㄦ埛淇℃伅
export function getUserInfo() {
  return http.get<USERAPI.UserInfo>('/ai-api/ai-auth/auth/info')
}

鍏朵粬

  • 甯冨眬鍜屽畬鎴愮殑浠g爜锛岃涓嬩竴绔?/li>

https://www.xamrdz.com/backend/3t41936488.html

相关文章: