阅读视图

发现新文章,点击刷新页面。

脚手架搭建项目框架(create-vite、vue-cli、create-vue、quasar-cli)

脚手架脚手架搭建项目框架

一. create-vite

npm create vite@latest(yarn create vite)安装脚手架命令

二. vue-cli

npm i -g @vue-cli安装脚手架命令

vue create project1创建项目

三. create-vue(vue官方的项目脚手架工具,内置了vite构建工具)项目开发中使用的脚手架

1.技术栈:

Create-vue脚手架 + Vite构建工具 + vue3组合式API (vue3选项式API)+ typescript + vue-router + pinia状态管理 (vuex状态管理)+ axios网络库 + vant3 UI组件库(element-plus UI组件库) + eslint + pretter + sass

2.脚手架搭建项目框架步骤:

1) npm init vue@latest 安装脚手架命令。

根据预设生成相应的配置文件(选择ts、vue-router、pinia、eslint、pretter)。

image.png

2) pinia配置:

npm i pinia-plugin-persist -S 安装pinia持久化存储插件。

创建stores文件夹→index.ts(创建pinia根存储,集成插件)

import { createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'//引入pinia持久化存储插件

const storeRoot = createPinia()
storeRoot.use(piniaPluginPersist)//集成插件
export default storeRoot

main.js入口文件(集成pinia)

import { createApp } from "vue";
import router from "./router";
import store from "./store";
import App from "./App.vue";
import 'normalize.css' // 重置样式

const app = createApp(App)
app.use(router);
app.use(store);
app.mount("#app");

stores文件夹→user.ts(定义store存储对象,持久化存储增加persist选项)

import {defineStore} from 'pinia'
/**
 * 定义名为useUserStore的存储对象
 *  defineStore方法
 *   第一个参数: 模块名称是唯一的
 *   第二个参数: 选项对象  state, actions, getters
 *                        data    methods   computed
 */
export const useUserStore = defineStore('user',{
    state(){
        return {
            account:null // 账户数据 {name,nick,password}  
        }
    },
    actions:{
        // 具体业务逻辑,可以是同步或异步操作
        saveAccount(account){
            this.account = account
        }
    },
    getters:{
        //getters中定义的方法名/计算属性名不能与state相同
        // userAccount:state => {
        //     return state.account
        // }//定义方式1
        userAccount(){
            return this.account
        }//定义方式2
    },
    persist: {//持久化存储
        enabledtrue,
        strategies: [
            {
                key: user,
                storagelocalStorage,
                paths: ['account'],
            },
        ],
    },
})

3)Sass、axios网络库、UI组件库需手动安装集成。状态管理vuex也需要手动安装集成。

npm i normalize.css -S 安装样式重置库(兼容浏览器)。main.ts中引入import'normalize.css'
npm i sass -d 安装sass(css预处理器,开发环境用)。
npm install axios -s 安装网络库axios(前后端数据交互)。

创建utils文件夹→request.ts中配置(创建axios实例,封装请求/响应拦截器)

import axios from 'axios'
import { Toast } from 'vant';
// 服务根地址
// export const baseURL = 'http://10.7.163.165:8089'  // 开发环境
/**
 * 创建axios实例
 *   封装baseURL
 */
const axiosInstance = axios.create({
    baseURL, // 服务根地址
    timeout: 3000, // 超时时间
})
/**
 * 请求拦截器
 */
axiosInstance.interceptors.request.use(
    config => {
        const token = localStorage.getItem('TOKEN')
        if(token){
            config.headers['Authorization'] = token
        }
        return config
    },
    error => {
        return Promise.reject(error)
    }
)
/**
 * 响应拦截器
 */
axiosInstance.interceptors.response.use(
    response => {
        return response.data
    },
    error => {
        const { response } = error
        if (response) {
            const status = response.status
            switch (status) {
                case 404:
                    Toast('资源不存在 404')
                    break
                case 401:
                    Toast('Unauthorized 身份验证凭证缺失!')
                    break
                case 403:
                    Toast('403 Forbidden - 拒绝访问!')
                    break
                case 500:
                    Toast('服务器出错')
                    break
                default:
                    Toast('出现异想不到的错误!')
                    break
            }
        }else {
            // 说明服务器连结果都没有返回,可能的原因有两种:
            /**
             * 1. 服务器崩掉了
             * 2. 前端客户端断网状态
             */
            if (!window.navigator.onLine) {
                // 判断为断网,可以跳转到断网页面
                Toast('网络不可用,请检查您的网络连接!')
                return
            } else {
                Toast('连接服务端出错!' + error?.message)
                return Promise.reject(error)
            }
        }
        return Promise.reject(error)
    }
)
export default axiosInstance
vant组件库安装与配置
  • npm i vant@latest-v3 安装vant组件库
  • npm i unplugin-vue-components -D 安装vant按需引入插件。vite.config.ts中引入集成
  • npm i postcss-pxtorem -D安装移动端适配插件,将px单位转化为rem单位。vite.config.ts中引入集成
  • npm i amfe-flexible -D安装移动端适配插件,适配不同屏幕尺寸。main.ts中引入

vite.config.ts

import { fileURLToPath, URLfrom 'node:url'

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

import Components from 'unplugin-vue-components/vite'//引入按需引入插件
import { VantResolverfrom 'unplugin-vue-components/resolvers'//引入按需引入插件

import postCssPxToRem from 'postcss-pxtorem'//引入移动端适配插件

import { viteMockServe } from 'vite-plugin-mock'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    Components({
      resolvers: [VantResolver()],//集成按需引入插件
    }),
    viteMockServe({//集成mock模拟接口数据插件
      // 更多配置见最下方
      supportTstrue,
      loggerfalse,
      mockPath'./mock/', // 文件位置
    }),
  ],
  resolve: {
    alias: {
      '@'fileURLToPath(new URL('./src', import.meta.url))
    }
  },
  css:{
    postcss:{
      plugins:[
        postCssPxToRem({//自适应,px转rem
          rootValue:75,//换算的基数(设计图750的根字体为75)
          propList:['*']//需要转换的属性,*代表全部
        })
      ]
    }
  },
  server:{//代理服务器
    proxy: {
      '/api': {
        target'http://124.71.63.13:8088/',
        changeOrigintrue,
        // rewrite: path => path.replace(/^\/api/, '')
      }
    }
  },
})

main.ts

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './stores'
import 'normalize.css' // 重置样式

// 导入vant函数组件样式
import 'vant/es/toast/style'
import 'vant/es/dialog/style'
import 'vant/es/notify/style'
import 'vant/es/image-preview/style'

//引入amfe-flexible屏幕适配插件
import 'amfe-flexible'

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

app.mount('#app')
elementplus组件库安装与配置
  • npm install element-plus --save安装elementplus组件库
  • npm install -d unplugin-vue-components unplugin-auto-import安装两个插件自动按需引入

vite.config.js集成插件

import { fileURLToPath, URL } from 'node:url'

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

import AutoImport from 'unplugin-auto-import/vite'//引入插件
import Components from 'unplugin-vue-components/vite'//引入插件
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'//引入插件

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    AutoImport({//集成插件
        resolvers: [ElementPlusResolver()],
    }),
    Components({//集成插件
        resolvers: [ElementPlusResolver()],
    }),
  ],
  resolve: {
    alias: {
      '@'fileURLToPath(new URL('./src', import.meta.url))
    }
  },
})

main.js引入elementplus样式,否则可能出现使用组件没效果。

import { createApp } from "vue";
import router from "./router";
import store from "./store";
import 'element-plus/dist/index.css';//引入elementplus样式
import App from "./App.vue";

import ElementPlus from 'element-plus';//完整引入elementplus,文件大小会很大。可以考虑按需引入

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

app.use(ElementPlus);//完整引入elementplus,文件大小会很大。可以考虑按需引入
app.mount("#app");
状态管理vuex安装与配置
  • npm install vuex@next(4.0.2) --save安装vuex插件
  • npm i vuex-persistedstate -s安装vuex持久化存储插件

main.js引入集成到vue

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

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

创建story文件夹→index.js文件集成持久化存储插件

import { createStore } from 'vuex'
import createPersistedState from 'vuex-persistedstate'

const store = createStore({
    // 集成持久化存储插件
    plugins:[createPersistedState({
        storage:sessionStorage,
        key:'storekey'
    })]
    state: {//状态数据
        count0
    },
    mutations: {//操作state状态。第一个参数:state对象,第二个参数:外部传入参数
        PLUS(state) {//方法
            // state.count = num
            state.count++
        },
    },
    /**
     * 定义操作mutations方法的方法
     * 供外部组件调用
     *   $store.dispatch('')
     *    1. 单向数流操作方式,保存状态数据以预期方式改变
     *    2. actions 异步操作
     *       mutations 同步操作
     */
    actions: {//操作mutations中的方法
        // plus(context) {//方法
        //     context.commit('PLUS')
        // }
        plus({ commit }) {//解构
            commit('PLUS')
        },
        chs({ commit },num) {//传参
            commit('CHS',num)
        }
    },
    getters: {//获取值,类似计算属性
        num(state) => { return state.count }
        // num: state => state.count
    }
})
export default store

3.解决引入vue组件ts报错(因为ts不识别.vue文件,需在env.d.ts中声明)

env.d.ts

// <reference types="vite/client" />
declare module '*.vue' {
    import { DefineComponent } from 'vue'
    const componentDefineComponent<{}, {}, any>
    export default component
}

4.目录结构介绍

image.png

  • npm install(npm i)下载依赖
  • npm run dev运行

5.打包

  • 将vue文件编译成浏览器能识别的js/html/css文件、ts编译成js文件、scss编译成css文件,压缩处理。
  • 编译后的文件存放在dist目录下(与src同级),都是html/css/js文件,将其部署到服务器上用户就可以用了。

接口环境配置: 开发环境(测试数据)/生产环境(用户使用的数据)

创建utils文件夹→request.ts中配置(创建axios实例,封装请求/响应拦截器,配置接口环境)

解决跨域问题走代理服务器:baseUrl地址为当前客户端地址,vite.config.ts配置代理服务器,代理服务器地址为目标地址(一般指测试地址/线上服务器地址)。

import axios from 'axios'
import { Toastfrom 'vant'

// 服务根地址
// export const baseURL = 'http://10.7.163.165:8089'  // 开发环境

// 生产环境 如果服务端没做跨域处理,使用代理服务器
// 走代理服务器,baseURL 地址配置为与当前客户端地址相同
export let baseURL = 'http://10.7.163.165:8089'  // 开发环境
/**
 * process.env.NODE_ENV
 *    production 生产环境
 *        npm run build
 *    development  开发环境
 *        npm run dev
 */
switch (process.env.NODE_ENV) {
    case 'production':
        baseURL = 'http://124.71.63.13'  // 生产环境
        break
    case 'development':
        baseURL = 'http://10.7.163.165:8089' // 开发环境
        break
}
/**
 * 创建axios实例
 *   封装baseURL
 */
const axiosInstance = axios.create({
    baseURL, // 服务根地址
    timeout3000, // 超时时间
})
/**
 * 请求拦截器
 */
axiosInstance.interceptors.request.use(
    config => {
        const token = localStorage.getItem('TOKEN')
        if (token) {
            config.headers['Authorization'] = token
        }
        return config
    },
    error => {
        return Promise.reject(error)
    }
)
/**
 * 响应拦截器
 */
axiosInstance.interceptors.response.use(
    response => {
        return response.data
    },
    error => {
        const { response } = error
        if (response) {
            const status = response.status
            switch (status) {
                case 404:
                    Toast('资源不存在 404')
                    break
                case 401:
                    Toast('Unauthorized 身份验证凭证缺失!')
                    break
                case 403:
                    Toast('403 Forbidden - 拒绝访问!')
                    break
                case 500:
                    Toast('服务器出错')
                    break
                default:
                    Toast('出现异想不到的错误!')
                    break
            }
        } else {
            // 说明服务器连结果都没有返回,可能的原因有两种:
            /**
             * 1. 服务器崩掉了
             * 2. 前端客户端断网状态
             */
            if (!window.navigator.onLine) {
                // 判断为断网,可以跳转到断网页面
                Toast('网络不可用,请检查您的网络连接!')
                return
            } else {
                Toast('连接服务端出错!' + error?.message)
                return Promise.reject(error)
            }
        }
        return Promise.reject(error)
    }
)
export default axiosInstance

tsconfig.json(解决request.ts中环境配置时process报错)

{
    "extends": "@vue/tsconfig/tsconfig.web.json",
    "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "@/*": ["./src/*"]
        },
        // 解决process.env.NODE_ENV报错,
        // 1.安装npm i @types/node -S
        // 配置"types": ["node"]
        "types": ["node"]
    },
    "references": [
        {
            "path": "./tsconfig.config.json"
        }
    ]
}

vite.config.ts配置代理服务器

import { fileURLToPath, URLfrom 'node:url'

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

import Components from 'unplugin-vue-components/vite'//引入按需引入插件
import { VantResolverfrom 'unplugin-vue-components/resolvers'//引入按需引入插件

import postCssPxToRem from 'postcss-pxtorem'//引入移动端适配插件

import { viteMockServe } from 'vite-plugin-mock'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    Components({
      resolvers: [VantResolver()],//集成按需引入插件
    }),
    viteMockServe({//集成mock模拟接口数据插件
      // 更多配置见最下方
      supportTstrue,
      loggerfalse,
      mockPath'./mock/', // 文件位置
    }),
  ],

  resolve: {
    alias: {
      '@'fileURLToPath(new URL('./src', import.meta.url))
    }
  },
  css:{
    postcss:{
      plugins:[
        postCssPxToRem({//自适应,px转rem
          rootValue:75,//换算的基数(设计图750的根字体为75)
          propList:['*']//需要转换的属性,*代表全部
        })
      ]
    }
  },
  server:{//代理服务器
    proxy: {
      '/api': {
        target'http://124.71.63.13:8088/',//目标地址
        changeOrigintrue,//是否跨域
//这里理解成用'/api'代替target里面的地址,比如我要调用'http://40.00.100.100:3002/user/add',直接写'/api/user/add'即可
        rewrite(path) => path.replace(/^**\/** api/, ''),
      }
    }
  },
})

npm run build打包

四. quasar-cli项目开发中使用的脚手架

关于quasar要求:

  • Node 12+用于Quasar CLI与Webpack,Node 14+用于Quasar CLI与Vite。
  • Yarn v1(强烈推荐),PNPM,或NPM。

npm i -g @quasar/cli 安装脚手架命令

npm init quasar 初始化quasar根据预设生成相应的配置文件

image.png

此时回车,会生成项目文件和目录

image.png

提示安装项目依赖,选择yes回车

image.png

quasar dev(npm run dev)运行

mock模拟后端,生成伪数据接口

官网:github.com/nuysoft/Moc…

1. 安装

npm i mockjs vite-plugin-mock 安装 mockjs和 vite-plugin-mock插件

2. vite.config.ts中集成插件

import { fileURLToPath, URLfrom 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

import Components from 'unplugin-vue-components/vite'//引入按需引入vant插件

import { VantResolverfrom 'unplugin-vue-components/resolvers'

import { viteMockServe } from 'vite-plugin-mock'//引入mock插件

// https://vitejs.dev/config/

export default defineConfig({

  plugins: [

    vue(),

    Components({

      resolvers: [VantResolver()],

    }),

    viteMockServe({//配置mock插件

      // 更多配置见最下方

      supportTstrue,

      loggerfalse,

      mockPath'./mock/', // 文件位置

    }),

  ],

  resolve: {

    alias: {

      '@'fileURLToPath(new URL('./src', import.meta.url))

    }

  }

})

3. mock文件夹mock接口数据

scr同级创建mock文件夹→account.ts(模块拆分,post请求config.body取参)


const accountList = []

/**

 * 用户注册

 */

export const mockRegister = {

    url:'/mock/account/register',

    method:'post',

    response:(config)=>{

        // 注册业务逻辑

        // 1. 获取用户名和密码

        const {username,password,headerimg} = config.body

        // 2. 保存用户信息

        // localStorage.setItem('USER',JSON.stringify({username,password,headerimg}))

        const user = {username,password,headerimg}

        accountList.push(user)

        // 3. 响应内容

        return {

            resultCode:1,

            resultInfo:'注册成功'

        }

    }

}

 

/**

 * 用户登录

 */

export const mockLogin = {

    url:'/mock/account/login',

    method:'post',

    response:(config)=>{

        // 登录业务逻辑

        // 1. 获取用户名和密码

        const {username,password,headerimg} = config.body

        // 2. 判断用户是否注册

        // let userstr = localStorage.getItem('USER')

        // let user = userstr? JSON.parse(userstr):''

        const user = accountList.find(item=>item.username==username && item.password==password)

        if(user){

            return {

                resultCode:1,

                resultInfo: {

                        username,

                        password,

                        headerimg

                }

            }

        }else{

            return {

                resultCode:-1,

                resultInof:'账户出错'

            }

        }

    }

}

scr同级创建mock文件夹→good.ts(模块拆分,get请求config.query取参)

import { goodsListData, bannerListData } from './data/goodsData'

/**

 * 商品列表

 */

export const goodsList = {

    url'/mock/goods/list',

    method'get',

    response(config:any) => {

        //get请求参数

        let { pageNo, pageSize } = config.query

        pageNo = pageNo || 1

        pageSize = pageSize || 10

        console.log('pageNo ', pageNo, ' pageSize :', pageSize)

        // 分页

        const startIndex = (pageNo - 1) * pageSize

        const endIndex = pageNo * pageSize

        const list = goodsListData.slice(startIndex, endIndex)

        if(list.length>0){

            return {

                resultCode1,

                resultInfo: {

                    list,

                },

            }

        }else{

            return {

                resultCode:-1,

                resultInfo:'没有数据'

            }

        }

    },

}

 

/**

 *  banner轮播

 */

export const bannerList = {

    url'/mock/banner',

    method'get',

    response() => {

        return {

            resultCode1,

            resultInfo: {

                list: bannerListData,

            },

        }

    },

}

scr同级创建mock文件夹→data文件夹→goodsData.ts(模块拆分,存放数据)


export const goodsListData = [

    {

        id49,

        shop'【苏宁生鲜】鲜美来东海带鱼600g 海鲜水产 鲜活冷冻',

        picture:

            'https://image1.suning.cn/uimg/b2c/newcatentries/0010128947-000000000614428161_1_800x800.jpg',

        product'【苏宁生鲜】鲜美来东海带鱼600g 海鲜水产 鲜活冷冻',

        price18.88,

        oldprice69,

        putaway1,

        detailnull,

        categoryname'川湘菜',

        categoryId3,

    },

    {

        id48,

        shop'【苏宁生鲜】恒都巴西牛腩块1kg 进口牛肉 精选肉类',

        picture:

            'https://image1.suning.cn/uimg/b2c/newcatentries/0010128947-000000000614167327_1_800x800.jpg',

        product'【苏宁生鲜】恒都巴西牛腩块1kg 进口牛肉 精选肉类',

        price18.98,

        oldprice49,

        putaway1,

        detailnull,

        categoryname'川湘菜',

        categoryId3,

    },

    {

        id45,

        shop'贝克巴斯(BECBAS)E50 厨房家用食物垃圾处理器 厨余垃圾粉碎机 无线开关免打孔',

        picture:

            'https://image3.suning.cn/uimg/b2c/newcatentries/0000000000-000000000616963357_2_800x800.jpg',

        product:

            '贝克巴斯(BECBAS)E50 厨房家用食物垃圾处理器 厨余垃圾粉碎机 无线开关免打孔',

        price38,

        oldprice67,

        putaway1,

        detailnull,

        categoryname'大家电',

        categoryId9,

    },

    {

        id44,

        shop'科龙(Kelon) 正1.5匹 定速 冷暖 空调挂机 ',

        picture:

            'https://image4.suning.cn/uimg/b2c/newcatentries/0000000000-000000000178605073_1_800x800.jpg',

        product'科龙(Kelon) 正1.5匹 定速 冷暖 空调挂机 ',

        price156.9,

        oldprice190,

        putaway1,

        detail'这个商品不错',

        categoryname'排骨',

        categoryId7,

    },

    {

        id42,

        shop'华帝浴室花洒 增压花洒 主体全铜花洒 沐浴莲蓬头【自营】H-CS0014-B1D.W',

        picture:

            'https://image2.suning.cn/uimg/b2c/newcatentries/0000000000-000000000604135232_1_800x800.jpg',

        product:

            '华帝浴室花洒 增压花洒 主体全铜花洒 沐浴莲蓬头【自营】H-CS0014-B1D.W',

        price18.87,

        oldprice90,

        putaway1,

        detailnull,

        categoryname'排骨',

        categoryId7,

    },

    {

        id41,

        shop'长虹(CHANGHONG) 大1匹 冷暖定频 快速制冷热 空调挂机 KFR-26GW/DHID(W1-J)+2',

        picture:

            'https://image2.suning.cn/uimg/b2c/newcatentries/0000000000-000000000126066901_1_800x800.jpg',

        product:

            '长虹(CHANGHONG) 大1匹 冷暖定频 快速制冷热 空调挂机 KFR-26GW/DHID(W1-J)+2',

        price18.48,

        oldprice35,

        putaway1,

        detailnull,

        categoryname'火锅',

        categoryId8,

    },

    {

        id40,

        shop'小米智米(SMARTMI)智能马桶盖 家用全自动冲洗即热式加热外置过滤器杀菌洁便器',

        picture:

            'https://image4.suning.cn/uimg/b2c/newcatentries/0000000000-000000000673521926_1_800x800.jpg',

        product:

            '小米智米(SMARTMI)智能马桶盖 家用全自动冲洗即热式加热外置过滤器杀菌洁便器',

        price34.98,

        oldprice47,

        putaway1,

        detailnull,

        categoryname'火锅',

        categoryId8,

    },

]

 

/**

 * 轮播数据

 */

export const bannerListData = [

    {

        id1,

        url'https://img.alicdn.com/imgextra/i3/2053469401/O1CN01g8ituT2JJiCsKjmDz_!!2053469401.png',

        content'商家1',

        number1,

    },

    {

        id11,

        url'https://img2.baidu.com/it/u=717979571,3244631707&fm=253&fmt=auto&app=138&f=JPEG?w=1280&h=400',

        content'舒适度满分',

        number1,

    },

    {

        id12,

        url'https://img1.baidu.com/it/u=1733684228,4177721799&fm=253&fmt=auto&app=138&f=JPEG?w=1200&h=500',

        content'曲线在召唤',

        number1,

    },

]

scr同级创建创建mock文件夹→index.ts(模块集成暴露)


import { bannerList, goodsList } from './goods'

import { mockRegister, mockLogin } from './account'

 

const goods = [bannerList, goodsList]  // 商品模块接口

const account = [mockLogin, mockRegister] // 个人中心接口

 

export default [...goods,...account]

4. utils文件夹→requestMock.ts(封装axios,不封装直接使用axios也行)

import axios from 'axios'
import { Toastfrom 'vant'

export let baseURL = 'http://10.7.163.159:5173'  

/**

 * 创建axios实例

 *   封装baseURL

 */

const axiosInstance = axios.create({

    baseURL, // 服务根地址

    timeout3000, // 超时时间

})

 

/**

 * 请求拦截器

 */

axiosInstance.interceptors.request.use(

    config => {

        const token = localStorage.getItem('TOKEN')

        if (token) {

            config.headers['Authorization'] = token

        }

        return config

    },

    error => {

        return Promise.reject(error)

    }

)

/**

 * 响应拦截器

 */

axiosInstance.interceptors.response.use(

    response => {

        return response.data

    },

    error => {

        const { response } = error

        if (response) {

            const status = response.status

            switch (status) {

                case 404:

                    Toast('资源不存在 404')

                    break

                case 401:

                    Toast('Unauthorized 身份验证凭证缺失!')

                    break

                case 403:

                    Toast('403 Forbidden - 拒绝访问!')

                    break

                case 500:

                    Toast('服务器出错')

                    break

                default:

                    Toast('出现异想不到的错误!')

                    break

            }

        } else {

            // 说明服务器连结果都没有返回,可能的原因有两种:

            /**

             * 1. 服务器崩掉了

             * 2. 前端客户端断网状态

             */

            if (!window.navigator.onLine) {

                // 判断为断网,可以跳转到断网页面

                Toast('网络不可用,请检查您的网络连接!')

                return

            } else {

                Toast('连接服务端出错!' + error?.message)

                return Promise.reject(error)

            }

        }

        return Promise.reject(error)

    }

)

export default axiosInstance

5. api文件夹→index.ts文件中定义接口

import axiosInstance from '@/utils/request'
import axiosMockInstance from '@/utils/requestMock'
import type{IResponse} from '@/types/types'


/**

 * 产品列表

 *   shopKey: 店铺名称

 *   productKey: 产品名称

 * @returns 

 */

export const RequestShopList = (pageNo:number,pageSize:number):Promise<IResponse>=>{

    return axiosInstance({

        method:'get',

        url:'/api/shop',

        params:{

            pageSize,

            pageNo,

        }

    })

}

/**

 * 轮播

 */

export const RequestBanner = ():Promise<IResponse>=>{

    return axiosInstance({

        method:'get',

        url:'/api/banner'

    })

}

/**

 * 登录

 */

export const RequestLogin = (username:string,password:string):Promise<IResponse>=>{

    return axiosMockInstance({

        method:'post',

        // url:'/api/member/login',

        url:'/mock/account/login',

        data:{

            username,

            password

        }

    })

}

/**

 * 注册

 */

export const RequestRegister = (username:string,password:string,headerimg:string):Promise<IResponse>=>{

    return axiosMockInstance({

        method:'post',

        url:'/mock/account/register',

        data:{

            username,

            password,

            headerimg

        }

    })

}

.vue文件中引入使用即可

❌