一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情。
Vue 网络请求
Vue 脚手架配置代理
配置单个代理
在 vue.config.js 中添加如下配置:
devServer: {
proxy: 'http://localhost:5000'
}
- 优点:配置简单,请求资源时直接发给前端(8080)即可。
- 缺点:不能配置多个代理,不能灵活的控制请求是否走代理。
- 工作方式:若按照上述配置代理,当请求了前端不存在的资源时,那么该请求会转发给服务器 (优先匹配前端资源)
配置多个代理
编写 vue.config.js 配置具体代理规则:
module.exports = {
devServer: {
proxy: {
'/api1': {
// 匹配所有以 '/api1'开头的请求路径
target: 'http://localhost:5000', // 代理目标的基础路径
changeOrigin: true,
// 把路径的 /api1 替换为空串
pathRewrite: { '^/api1': '' },
},
'/api2': {
// 匹配所有以 '/api2'开头的请求路径
target: 'http://localhost:5001',
changeOrigin: true,
pathRewrite: { '^/api2': '' },
},
},
},
}
/*
changeOrigin 设置为 true 时,服务器收到的请求头中的 host:localhost:5000
changeOrigin 设置为 false 时,服务器收到的请求头中的 host:localhost:8080
changeOrigin 默认为 true
*/
- 优点:可以配置多个代理,且可以灵活的控制请求是否走代理。
- 缺点:配置略微繁琐,请求资源时必须加前缀
vue 2.x 全局配置 axios
实际项目开发中,几乎每个组件中都会使用 axios 发起数据请求。此时会遇到如下两个问题:
- 每个组件中都需要导入
axios(代码臃肿) - 每次发请求都需要填写完整的请求路径(不利于后期的维护)
在 main.js 文件中进行配置:
// 配置请求根路径
axios.defaults.baseURL = 'http://api.com'
// 把 axios 挂载到 Vue 原型上
Vue.prototype.$http = aixos
优点:每个组件可以通过 this.$http.get 直接发起请求,无需再导入 axios ;若根路径发生改变,只需修改 axios.defaults.baseURL ,有利于代码维护。
缺点:无法实现 API 的复用。即多个组件需要对同一个接口发起请求,那么每个组件都需要重复书写 this.$http.get('/users') 类似的代码,造成冗余。(视频上的说法,个人认为真正的缺点是如果存在多个根路径,这种方式无法解决,所以才会有下面的改进方式。)
改进:对于每一个根路径,独立封装一个 request.js 模块,组件导入所需根路径对应的 axios 进行使用。
import axios from 'axios'
// 创建 axios 实例
const request = axios.create({
baseURL: 'http://api.taobao.com',
})
export default request
全局路由导卫
使用请求拦截配置加载进度条
安装进度条
npm i nprogress
axios.interceptors.request 请求拦截
axios.interceptors.response 响应拦截
// 导入NProgress 包进度条
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
// 配置请求的跟路径
axios.defaults.baseURL = "https://lianghj.top:8888/api/private/v1/"
// 设置请求拦截
axios.interceptors.request.use(config=>{
// 开始进度条
NProgress.start()
// 添加请求头请求内部API
config.headers.Authorization = window.sessionStorage.getItem('token')
return config // 注意都需要return config 不然报错
})
// 响应拦截
axios.interceptors.response.use(config=>{
// 结束进度条
NProgress.done()
return config
})
// 挂载全局axios
Vue.prototype.$http = axios
注意:都需要return config 不然报错
Vue 脚手架
创建 Vue 项目
- 全局安装 vue 脚手架:
npm i -g @vue/cli - 创建项目:
vue create project-name - 运行项目:
npm run serve - 暴露 webpack 配置:
vue inspect > output.js
Vue 脚手架项目结构
├── node_modules
├── public
│ ├── favicon.ico: 页签图标
│ └── index.html: 主页面
├── src
│ ├── assets: 存放静态资源
│ │ └── logo.png
│ │── component: 存放组件
│ │ └── HelloWorld.vue
│ │── App.vue: 汇总所有组件
│ │── main.js: 入口文件
├── .gitignore: git 版本管制忽略的配置
├── babel.config.js: babel 的配置文件
├── package.json: 应用包配置文件
├── README.md: 应用描述文件
├── package-lock.json:包版本控制文件
index.html 代码分析:
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8" />
<!-- 针对IE浏览器的一个特殊配置,含义是让IE浏览器以最高的渲染级别渲染页面 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- 开启移动端的理想视口 -->
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<!-- <%= BASE_URL %> 表示 public 文件夹路径 -->
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<!-- 拿 package-lock.json 的 name 作为标题 -->
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<!-- 当浏览器不支持js时noscript中的元素就会被渲染 -->
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<!-- 容器 -->
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
关于不同版本的 Vue
vue.js与vue.runtime.xxx.js的区别:
import Vue from 'vue'默认导入vue.runtime.esm.jsvue.js是完整版的 Vue,包含:核心功能 + 模板解析器vue.runtime.xxx.js是运行版的 Vue,只包含:核心功能;没有模板解析器
vue.runtime.xxx.js没有模板解析器,故不能使用template配置项,需使用render函数接收到的createElement函数去指定具体内容
import Vue from 'vue'
import App from './App.js'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
// render()
render: function(createElement) {
return createElement('h1', 'Hello Vue')
}
render: createElement => createElement(App)
vue.config.js 配置文件
- 使用
vue inspect > output.js可以查看到 Vue 脚手架的默认配置。 - 使用
vue.config.js可以对脚手架进行个性化定制,详情(opens new window)