vue3+ts+axios+Ant Design of Vue2配套使用踩坑

6,649 阅读2分钟

介绍🎉

vue3-ts-model 是一套集成 vue3vue-routrtsAnt Design of Vueaxios的模板。 基于vuecli4搭建, 对axios实现简易封装, 对Ant Design of Vue实现按需加载

每次搭建新的项目,都要重复安装路由、ui、axios,还需要对ui配置按需加载、在稍稍封装下axios便于易用,完了简化这个重复过程,就搞了这么个模板。

gitHub 地址

vue3-ts-model-😊😊🎉

axios的简易封装

新建utils\http.ts

import type { AxiosResponse } from 'axios'
import axios from 'axios'
import router from '../router'
axios.defaults.baseURL = process.env.VUE_APP_URL // 为了方便添加不同环境的请求地址,所以地址放在环境文件中
axios.defaults.withCredentials = true
const http = axios.create({
  baseURL: process.env.VUE_APP_BASEURL,
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json'
  }
})
http.interceptors.response.use(function (response: AxiosResponse<any>) {
  // 没有token,缺少登录令牌
  if (response.data.code === 2020) {
    router.replace('/login')
  }
  // token过期,登录令牌无效
  if (response.data.code === 2030) {
    router.replace('/login')
  }
  return response.data
}, function (err: any) {
  return Promise.reject(err)
})
export default http

新建hooks\useRequest.ts

import http from '../utils/http'
// 获取天气
function getWeather (params: any) {
  return http.get('Weather/get_weather', params)
}
export { getWeather }

Ant Design of Vue 按需加载

必要的插件

"dependencies": {
    "ant-design-vue": "^2.0.0-rc.2"
},
"devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.0",
    "babel-plugin-import": "^1.13.3",
    "less": "^3.0.4",
    "less-loader": "^5.0.0"
  }

新建 babel.config.js 文件

module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ],
  plugins: [
    [
      "import",
      { libraryName: "ant-design-vue", libraryDirectory: "es", style: true }
    ]
  ]
}

在 main.ts 中添加

import { Button, Radio, Input, Tag, Menu, Dropdown, InputNumber, Empty, Form, message } from 'ant-design-vue'
const app = createApp(App)
app.config.globalProperties.$message = message // 全局挂在message
app.use(Button).use(Radio).use(Input).use(Tag).use(Menu).use(Dropdown).use(InputNumber).use(Empty).use(Form)

如果遇到 .bezierEasingMixin(); 错误,在main.ts中添加

css: {
    loaderOptions: {
      less: {
        javascriptEnabled: true,
      }
    }
  },

Ant Design of Vue 修改主题颜色

Ant Design of Vue 是使用less开发的,所以在less那里做下手脚就可以

css: {
    loaderOptions: {
      less: {
        modifyVars: {
          'primary-color': '#1272a2'
        },
        javascriptEnabled: true,
      }
    }
  },

请求使用 & 错误捕获

// 先引入请求文件
import { getWeather } from '../hooks/useRequest'
在setup 中使用处理
try {
        const result = await getWeather({})
        if (result.code === 1) {} else {}
} catch (error) {
        globalProperties.$message.error(error.toString())
}

处理 Property 'code' does not exist on type 'AxiosResponse<any>'. 错误

const result: any = await getWeather() //result 设置any 类型

封装 useCurrentInstance

在setup中,无论是获取挂载在全局的属性还在获取上下文,都需要使用getCurrentInstance(), 考虑到许多组件都会使用,就单独搞出来封装一下。 新建 hooks\useCurrentInstance.ts

import { getCurrentInstance } from 'vue'
export default function useCurrentInstance () {
  const { appContext } = getCurrentInstance()
  const globalProperties = appContext.config.globalProperties
  return {
    globalProperties
  }
}

组件中使用

// 先引入请求文件
import useCurrentInstance from '../hooks/useCurrentInstance'
在setup 中使用处理
const { globalProperties } = useCurrentInstance()

解决 类型“ComponentInternalInstance | null”上不存在属性“appContext”。 错误

import { ComponentInternalInstance, getCurrentInstance } from 'vue' // 添加 ComponentInternalInstance
export default function useCurrentInstance () {
  const { appContext } = getCurrentInstance() as ComponentInternalInstance // 断言到 ComponentInternalInstance
}

注意的点:千万不要在getCurrentInstance() 中获取ctx来使用router等东西,这玩意在生成环境下结构就不一样了,会报undefined。可以使用proxy。(我第一次搞vue3就卡在这里3天😂)

const { appContext, proxy } = getCurrentInstance()
// proxy.$parent
// proxy.$router
这样就没问题了。

解决升级更新less-loader后报错,无法启动项目的问题

报错信息

Module build failed (from ./node_modules/less-loader/dist/cjs.js):
ValidationError: Invalid options object. Less Loader has been initialized using an options object that does not match the API schema.
 - options has an unknown property 'javascriptEnabled'. These properties are valid:
   object { lessOptions?, additionalData?, sourceMap?, webpackImporter? }
    at validate (D:\vue3-xm\jvkf-z-admin\node_modules\less-loader\node_modules\schema-utils\dist\validate.js:104:11)
    at Object.lessLoader (D:\vue3-xm\jvkf-z-admin\node_modules\less-loader\dist\index.js:26:29)

主要还是在于结构发生变化了

less: {
  lessOptions: {    // 多了一级, 加上就可以
    modifyVars: {
      'primary-color': '#1272a2'
    },
    javascriptEnabled: true
  }
}

解决v-model的 'v-model' directives require no argument. 错误

rules: {
    'no-v-model-argument': 'off'
}
or
extends: [
    // '@vue/standard'
],