Vue CLI
介绍
CLI是Command-Line Interface, 翻译为命令行界面, 但是俗称脚手架。
Vue CLI是一个官方发布 vue.js 项目脚手架,使用 vue-cli 可以快速搭建Vue开发环境以及对应的webpack配置。
前提
Vue.js官方脚手架工具就使用了webpack模板对所有的资源会压缩等优化操作,它在开发过程中提供了一套完整的功能,能够使得我们开发过程中变得高效。
安装
执行命令:npm install -g @vue/cli。 这里安装的是最新版本的vue cli。
如果要使用Vue CLI2,需要拉去脚手架2的模板:npm install -g @vue/cli-init
脚手架创建项目
Vue CLI2初始化项目
- 命令: vue init webpack my-project。
- 目录结构:
- 启动开发模式:
查看package.json:
dev 是启动开发服务器; start也是指向dev命令;build是生产环境打包代码。
Vue CLI2 Runtime+compiler 和Runtime-only的区别
官方文档: https://cn.vuejs.org/v2/guide/installation.html#%E8%BF%90%E8%A1%8C%E6%97%B6-%E7%BC%96%E8%AF%91%E5%99%A8-vs-%E5%8F%AA%E5%8C%85%E5%90%AB%E8%BF%90%E8%A1%8C%E6%97%B6
-
如下,创建项目时会有Vue build的选项: runtime + compiler 和runtime-only。
-
两者的区别主要在于main.js中,选择runtime-only的主app中会使用render函数:
-
vue中主app渲染模板的流程:
使用runtime + compiler 创建项目时:实例化vue实例化采用传入将App传入template模板的方式。new Vue({ el: '#app', components: { App }, template: '<App/>' })
① 传入template参数传入子组件模板,会赋值给vue实例的options参数。
② 将模板解析为为ast(abstract syntax tree 抽象语法树)。
③ 将ast编译为render函数。
④ 通过render函数生成virtual DOM。
⑤ 将Virtual DOM 更新到真实UI页面上。
使用runtime-only创建项目时:实例化vue实例化时,将App传入render函数,没有经过解析模板和编译ast,相当于少了以上①②步。
所以使用runtime-only时效率更高,源代码更少,这就是少的6kb代码的原因。new Vue({ el: '#app', render: h => h(App) })
-
render函数:
实例化vue对象时,render函数的入参实际是createElement函数。
如下:可以用render函数代替传入compnents和template的方式对vue进行实例化。
createElement函数有两种用法:① 传入三个参数,创建标签。 ② 直接传入组件。创建的标签或者组件会替换掉index.html中id是#app的标签。import Vue from 'vue' import App from './App' Vue.config.productionTip = false // 打印App,查看App中是否有template console.log(App) new Vue({ el: '#app', // components: { App }, // template: '<App/>', render: function (createElement) { // 1. 普通用法 createElement('标签名', {属性key:value}, [标签内容]) // return createElement( // 'h2', // {'class': 'box'}, // ['h2 message', createElement('button', {}, ['按钮'])]) // 2. 传入组件 return createElement(App) } })
如上代码中,有对App进行打印,可以看到App中不包含template,这是因为项目通过vue-template-compiler编译,已经将template转换为了render函数。
npm run build 流程
npm run build 流程
Vue CLI3初始化项目
- 命令: vue create “项目名称”
- 项目目录:
CLI3的设计理念就是“零配置”,所以创建完项目后,已经看不到CLI2创建项目的build和config目录。
index.html移入了public目录,对应于CLI2创建的static目录。
- 修改配置的三种方式:
项目实际的配置是隐藏在了cli-server下的webpack.config.js中,如果要修改默认配置,可以通过以下两种方式:
① 命令行执行vue ui,打开UI页面,导入项目后,在页面上可以配置项目:
② 创建vue.config.js文件:
在项目目录下创建vue.config.js文件,项目运行时会自动合并该配置文件与默认配置文件。
Vue-Router
官网:https://router.vuejs.org/zh/
路由的发展阶段
后端路由阶段
早期的网站开发整个HTML页面都是由服务器来渲染的,服务器直接生产渲染好对应的HTML页面, 返回给客户端进行展示。
一个网站中每个页面有自己对应的URL,URL会发送到服务器, 服务器会通过正则对该URL进行匹配, 并且最后交给一个Controller进行处理,Controller进行各种处理, 最终生成HTML或者数据, 返回给前端,这就完成了一个IO操作。这种操作就是后端路由。
优点:当我们页面中需要请求不同的路径内容时,交给服务器来进行处理,服务器渲染好整个页面,并且将页面返回给客户端。这种情况下渲染好的页面不需要单独加载任何的js和css,可以直接交给浏览器展示, 也有利于SEO的优化。
缺点:整个页面的模块由后端人员来编写和维护的,前端开发人员如果要开发页面,需要通过PHP和Java等语言来编写页面代码。而且通常情况下HTML代码和数据以及对应的逻辑会混在一起,编写和维护都是非常糟糕的事情。
前后端分离阶段
随着Ajax的出现,有了前后端分离的开发模式。
后端只提供API来返回数据,前端通过Ajax获取数据,并且可以通过JavaScript将数据渲染到页面中(需要通过js操作DOM)。这样做最大的优点就是前后端责任的清晰,后端专注于数据上,前端专注于交互和可视化上。并且当移动端(iOS/Android)出现后,后端不需要进行任何处理,依然使用之前的一套API即可。目前很多的网站依然采用这种模式开发。
单页面富应用阶段
其实SPA(Single Page Application)最主要的特点就是在前后端分离的基础上加了一层前端路由,也就是前端来维护一套路由规则。前端路由的核心是:改变URL,但是页面不进行整体的刷新。
修改URL,不刷新页面的方法
Location.hash
URL的hash也就是锚点(#),本质上是改变window.location的href属性。我们可以通过直接赋值location.hash来改变href,但是页面不发生刷新。
初始状态:
通过location.hash修改url,页面没有刷新:
HTML5的history模式
history接口是HTML5新增的,它有五种模式改变URL而不刷新页面。
- history.pushState、history.back()和history.forward():
pushState()类似于压栈的方式,可以用**history.back()**返回上一个页面,**history.forward()**进入下一个页面。
- history.replaceState(): 与pushState区别就是replace是替换url,不能返回。
- history.go():需要搭配pushState()使用
history.back() 等价于 history.go(-1),history.forward() 则等价于 history.go(1),这三个接口等同于浏览器界面的前进后退。
安装路由插件
vue-router是基于路由和组件的,路由用于设定访问路径,将路径和组件映射起来。在vue-router的单页面应用中,页面的路径的改变就是组件的切换。
步骤一:安装vue-router:
npm install vue-router --save
步骤二: 在模块化工程中使用它(因为是一个插件, 所以可以通过Vue.use()来安装路由功能)
第一步:导入路由对象,并且调用 Vue.use(VueRouter);
第二步:创建路由实例,并且传入路由映射配置;
第三步:在Vue实例中挂载创建的路由实例;
路由插件使用
使用vue-router的步骤
第一步:创建路由组件;
第二步:配置路由映射—组件和路径映射关系;
第三步:使用路由—通过和;
router-link:该标签是一个vue-router中已经内置的组件,它会被渲染成一个a标签。
router-view:该标签会根据当前的路径,动态渲染出不同的组件。网页的其他内容,比如顶部的标题/导航,或者底部的一些版权信息等会和router-view处于同一个等级。
在路由切换时,切换的是router-view挂载的组件,其他内容不会发生改变。
配置默认路由和修改history模式
默认路由
首次进入页面时要加载首页,可以将“/”重定向到“/home”
修改history模式
默认情况下,路由为hash模式,即锚点(#)。
如果想修改为H5的history模式,只需要在实例化路由对象时,传入mode参数为history即可。
router-link其他属性
tag:tag可以指定router-link之后渲染成什么组件,比如上面的代码会被渲染成一个li元素,而不是a。
replace:replace不会留下history记录,所以指定replace的情况下,后退键返回不能返回到上一个页面中。
active-class:当router-link对应的路由匹配成功时,会自动给当前元素设置一个router-link-active的class,设置active-class可以修改默认的名称。在进行高亮显示的导航菜单或者底部tabbar时,会使用到该类。但是通常不会修改类的属性,会直接使用默认的router-link-active即可。
如下图,被点击中会加上router-link-active类。
如果需要在选中时触发不同的样式,可以创建router-link-active样式类。
如果不想使用router-link-active这个名称,可以在实例化路由对象时,传入linkActiveClass参数,value设置为active,在使用时,就可以定义名称为active的样式类。
通过代码进行路由跳转
定义button点击事件,在点击事件中通过this.
r
o
u
t
e
r
.
p
u
s
h
进
行
跳
转
,
p
u
s
h
其
实
就
是
h
i
s
t
o
r
y
.
p
u
s
h
S
t
a
t
e
(
)
。
t
h
i
s
.
router.push进行跳转,push其实就是history.pushState()。 this.
router.push进行跳转,push其实就是history.pushState()。this.router.replace,也可以进行路由跳转,类似于history.replaceState()。
使用$router.path判断当前url是否已经是要跳转的url,重复跳转会报错。
注: 不要绕过vue-router直接使用history.pushState()进行跳转。
动态路由
在某些情况下,一个页面的path路径可能是不确定的,比如进入用户界面时,希望是如下的路径:/user/aaaa或/user/bbbb。
除了有前面的/user之外,后面还跟上了用户的ID。这种path和Component的匹配关系,称之为动态路由(也是路由传递数据的一种方式)。
- 定义动态路由:
采用“:名称”的方式定义动态路由。
- router-link通过v-bing绑定to属性,动态拼接url:
- 如果子组件需要拿到userID信息展示,可以通过
r
o
u
t
e
.
p
a
r
a
m
s
获
取
当
前
选
中
的
路
由
信
息
对
象
,
从
中
拿
到
动
态
路
由
参
数
:
注
:
如
果
当
前
路
由
不
是
动
态
路
由
,
拿
到
的
route.params获取当前选中的路由信息对象,从中拿到动态路由参数: 注: 如果当前路由不是动态路由,拿到的
route.params获取当前选中的路由信息对象,从中拿到动态路由参数:注:如果当前路由不是动态路由,拿到的route.params是一个空对象。
路由的懒加载
路由中通常会定义很多不同的页面,一般情况下,这些页面最后被打包 是放在一个js文件中。但是,页面这么多放在一个js文件中必然会造成这个js文件非常的大。如果一次性从服务器请求下来这个页面, 需要花费一定的时间,甚至用户的电脑上还出现了短暂空白的情况。使用路由懒加载就可以避免这种情况。
路由懒加载的主要作用:就是将路由对应的组件打包成一个个的js代码块,只有在这个路由被访问到的时候,才加载对应的组件代码。
不采用懒加载的情况下打包后,会生成3个js文件,其中app是放的业务代码;vender是vue的代码;manifest是vue底层的一些代码(待研究)。
实现懒加载的三种方式:
方式一: 结合Vue的异步组件和Webpack的代码分析.
const Home = resolve => { require.ensure([’…/components/Home.vue’], () => { resolve(require(’…/components/Home.vue’)) })};
方式二:AMD写法
const About = resolve => require([’…/components/About.vue’], resolve);
方式三(推荐使用):在ES6中, 我们可以有更加简单的写法来组织Vue异步组件和Webpack的代码分割.
const Home = () => import(’…/components/Home.vue’)
导入组件时,采用以下方式导入,就可以实现懒加载:
重新打包,每个组件会对应一个js文件:
路由嵌套
嵌套路由是一个很常见的功能:比如在home页面中,我们希望通过/home/news和/home/message访问一些内容,一个路径映射一个组件, 访问这两个路径也会分别渲染两个组件。
路径和组件的关系如下:
-
创建子组件:
-
配置子路由:
① 在父路由中配置children属性,值为数组形式,可以配置多个子路由;
② 子路由的path不需要添加完整的url,也不需要添加斜杠。如:完整路由为:/home/news,在子路由的path中只需要配置news。
③ 配置默认子路由,进入页面时默认加载其中一个子页面。
-
在父组件中配置子组件路由信息:
注:这里的to属性要配置完整的路由信息。
vue-router传递参数
传递参数主要有两种方式:params和query
params方式(参考动态路由配置)
配置动态路由格式: /router/:id
传递的方式:在path后面跟上对应的值
传递后形成的路径: /router/123, /router/abc
query方式
配置路由格式: /router,也就是普通配置;
传递的方式:对象中使用query的key作为传递方式
传递后形成的路径: /router?id=123, /router?id=abc
- 在router-link中跳转路由并传参:
- 在js中跳转并传递参数:
- 组件中获取传递的参数:
在组件中通过$route.query获取传递的参数对象。
- 最终效果:
导航守卫
需求:跳转首页、关于、档案时,动态修改页面的title。
方法一: 在每个组件生命周期created函数中动态修改document.title=“XXX”;
方法二: 使用导航守卫。vue-router提供的导航守卫主要用来监听路由的进入和离开的。vue-router提供了beforeEach和afterEach的钩子函数,它们会在路由即将改变前和改变后触发。
全局导航守卫
-
定义全局导航守卫:
① 在index.js中使用router.beforeEach监听每次路由的切换。
② beforeEach函数会传入3个参数:
to:即将要进入的目标的路由Route对象;
from:当前导航即将要离开的路由Route对象;
next:调用该方法后, 才能进入下一个钩子;
③ 如果存在路由嵌套,to.meta会是{},所以最好从to.matched中获取meta。to.matched是一个数组,如果存在路由嵌套,则会存在多个路由信息,默认父路由放在下标0的位置,所以这里获取to.matched[0].meta。
-
在路由中meta中创建自定义字段:
其他导航守卫
- 如果是后置钩子,也就是afterEach,只有两个参数to和from,因为已经切换过路由了,所以不需要再调用next()函数。
- 路由独享的守卫:与全局前置守卫的方法参数是一样的。
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
- 组件内的守卫:
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
官方文档:https://router.vuejs.org/zh/guide/advanced/navigation-guards.html#%E8%B7%AF%E7%94%B1%E7%8B%AC%E4%BA%AB%E7%9A%84%E5%AE%88%E5%8D%AB
keep-alive
keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。有两个非常重要的属性:
include: 字符串或正则表达(多个组件名称直接),只有匹配的组件(组件name)会被缓存。
exclude: 字符串或正则表达式,任何匹配的组件(组件name)都不会被缓存。
① 使用keep-alive包裹router-view,所有路径匹配到的视图组件都会被缓存:
② 使用keep-alive包裹后,可以使用activated和deactived方法来监听组件是否活跃(只有使用keep-alive时才能使用这两个方法):
③ 如下图,使用生命周期函数进行验证:
第一次加载组件时调用了created方法,前往其他路由时,没有销毁组件,再回来时也不需要重新创建组件;
Vuex
介绍
Vuex是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
Vuex提供一个在多个组件间共享状态的插件,把需要多个组件共享的变量全部存储在一个对象里面。然后,将这个对象放在顶层的Vue实例中,让多个组件可以使用。并且这个对象的修改是响应式的。
比如用户的登录状态、用户名称、头像、地理位置信息、商品的收藏、购物车中的物品等等。这些状态信息,都可以放在统一的地方,对它进行保存和管理,而且它们还是响应式的。
安装
-
安装vuex:执行:npm install vuex --save (运行时依赖)
-
安装Devtools(可选):在谷歌商店中搜索devtools,然后安装
重新打开浏览器,打开F12,多了一个Vue的选项:
使用
下图是vuex官方提供的vuex的使用流程。
state:存放共享数据,在多个组件中可以使用。
Devtools:vuex的一个浏览器插件,通过mutations修改共享数据时,每次修改都会记录下来,方便问题跟踪定位。
mutations:修改state中的共享数据要通过mutations操作,这样才能记录在Devtools中。
actions:如果有异步操作,例如:网络请求要放在actions中,拿到结果后再提交到mutations中去修改state数据。反之,如果没有异步操作,不需要使用actions,可以直接去mutations中修改statue数据。
- 创建store/index.js,用于存放vuex代码:
import Vue from 'vue'
import Vuex from 'vuex'
// 1. 安装Vuex 插件
Vue.use(Vuex)
// 2. 创建对象
const store = new Vuex.Store({
// state中定义变量
state: {
counter: 1000
},
// mutations中定义修改state中变量的函数
mutations: {
// mutations中定义的函数,默认会将state作为入参传入,可以从中获取要修改的参数
add (state) {
state.counter++;
},
sub (state) {
state.counter--;
}
},
actions: {},
getters: {},
modules: {}
});
// 3. 导出store对象
export default store
- main.js导入vuex并在主app中注册vuex:
import Vue from 'vue'
import App from './App'
import store from './store'
Vue.config.productionTip = false;
new Vue({
el: '#app',
// 注册vuex
store,
render: (createElement) => createElement(App)
});
- 主App.vue中通过 s t o r e . s t a t e 获 取 v u e x 的 变 量 以 及 store.state获取vuex的变量以及 store.state获取vuex的变量以及store.commit调用mutations中定义的函数:
<template>
<div id="app">
<h2>-----------App.vue---------</h2>
<!-- 通过$store.state获取vuex中定义的变量 -->
<h2>{{$store.state.counter}}</h2>
<button @click="addition">+</button>
<button @click="subduction">-</button>
<h2>-----------HelloVuex.vue---------</h2>
<hellovuex></hellovuex>
</div>
</template>
<script>
import HelloVueX from "./components/HelloVueX";
export default {
name: 'App',
data() {
return {
message: "这是App组件"
}
},
methods: {
subduction() {
// vuex mutations中定义的函数要通过$store.commit调用,传入函数名
this.$store.commit("sub")
},
addition() {
this.$store.commit("add")
}
},
components: {
hellovuex: HelloVueX
}
}
</script>
<style>
</style>
- 如下,通过Devtools记录vuex state中变量的改变记录:
Vuex的核心概念
官方文档:https://vuex.vuejs.org/zh/guide/modules.html
state
Vuex提出使用单一状态树或单一数据源,英文名称是Single Source of Truth。如果状态信息保存到多个Store对象中的,那么管理和维护等等都会变得特别困难。
所以Vuex使用单一状态树来管理应用层级的全部状态。单一状态树能够让我们最直接的方式找到某个状态的片段,而且在之后的维护和调试过程中,也可以非常方便的管理和维护。
总之,就是只能创建一个Vuex对象来管理状态信息。
Getters
有时候需要从store中获取一些state变异后的状态,类似于组件中的计算属性,要经过计算后再作为属性值。
基本使用
- 在getters中定义函数:
const store = new Vuex.Store({
state: {
counter: 1000,
students: [
{id: 1000, name: "A", age:10},
{id: 1001, name: "B", age:12},
{id: 1002, name: "C", age:16},
{id: 1003, name: "D", age:21},
]
},
getters: {
// 在getters中定义的函数类似于组件的计算属性;默认会传入state
getGreaterStudents(state) {
return state.students.filter(student => student.age > 20)
}
}
});
- 在组件中使用:
<template>
<div id="app">
<h2>-----------App.vue---------</h2>
<!-- 通过$store.getters获取其中定义的函数 -->
{{$store.getters.getGreaterStudents}}
</div>
</template>
调用其他getters函数
getters中定义函数时,可以传入第二个参数getters,从中可以调用在getters中定义的其他函数。
getters: {
getGreaterStudents(state) {
return state.students.filter(student => student.age > 20)
},
// 调用getGreaterStudents函数
getGreaterStudentsNum(state, getters) {
return getters.getGreaterStudents.length
}
}
传参的getters函数
如下,获取年龄大于age的学生信息数组:age动态传入。
对于动态传入参数的getters函数,返回一个函数,在调用除直接调用。
getters: {
getGreaterStudents(state) {
return age => {
return state.students.filter(student => student.age > age)
}
}
}
<template>
<div id="app">
<h2>-----------App.vue---------</h2>
<!-- $store.getters.getGreaterStudents不需要带括号调用,已经拿到了返回了函数,所以这里不需要()(20) -->
{{$store.getters.getGreaterStudents(20)}}
</div>
</template>
Mutation
- Vuex的store状态的更新唯一方式:提交Mutation。
- Mutation主要包括两部分:
字符串的事件类型(type),即mutation中定义的函数名称;
一个回调函数(handler),该回调函数的第一个参数就是state。 - 在通过mutation更新数据的时候, 有可能希望携带一些额外的参数,参数被称为是mutation的载荷(Payload),载荷可以是普通的数据类型,也可以是对象。
mutations: {
// 第二个传入的动态参数
add (state, count) {
state.counter += count;
}
}
methods: {
addition() {
let count = 5;
// 在组件中使用commit提交是,第二个参数是要动态传入的参数(可以是对象格式)
this.$store.commit("add", count)
}
}
-
Mutation提交方式:
① 字符串格式:this. s t o r e . c o m m i t ( " a d d " , c o u n t ) ; ② 对 象 格 式 : t h i s . store.commit("add", count); ② 对象格式: this. store.commit("add",count);②对象格式:this.store.commit({type: “add”, count: count }); 接收参数也需要修改为:// 1. 组件中提交改为对象格式 this.$store.commit({ type: "add", count: count }); // 2. mutation中函数参数需要从payload对象中获取 add (state, payload) { state.counter += payload.count; }
-
Mutation响应规则:
① state中的对象添加数据,要使用Vue.set(state.xxx, key/index, value)。否则,添加的数据不会是响应式的。
② state中的对象删除数据,要使用Vue.delete(state.xxx, key/index)。 -
Mutation类型常量:
当Mutation中的方法越来越多, 在声明和组件中调用时,就有可能会写错,很常见的方案就是使用常量替代Mutation事件的类型(也就是事件名称)。
将这些常量放在一个单独的文件中, 方便管理以及让整个app所有的事件类型一目了然。
Action
基本用法
Action类似于Mutation,Mutation中不能进行异步操作,异步操作都需要放在Action。
注:异步操作需要通过action,但是修改state最终还是只能通过mutation。
Action事件完成后回调函数
如果action处理完异步请求后,还需要做其他事情,这时可以通过调用action时,传入的参数为一个函数,在action中调用。
更好的方法是在action事件中使用promise处理异步请求,在组件中通过promise处理成功后的.then处理要做的事情。
Modules
Vue使用单一状态树,意味着很多状态都会交给Vuex来管理,当应用变得非常复杂时,store对象就会变得相当臃肿。
Vuex允许将store分割成模块(Module), 每个模块拥有自己的state、mutations、actions、getters等。
注:getters/actions/mutations中的参数/事件名称不能和根模块冲突。如果冲突,会先执行根模块事件,再执行子模块事件。
子模块actions事件的context,可以拿到rootGetters、rootState:
Store代码目录规范
当Vuex帮助我们管理过多的内容时, 好的项目结构可以让代码更加清晰。
axios
官方文档:http://www.axios-js.com/
介绍和安装
axios 是Vue作者推荐使用的网络请求库。
功能特点:
在浏览器中发送 XMLHttpRequests 请求;在 node.js 中发送 http请求;支持 Promise API;拦截请求和响应;转换请求和响应数据等等。
支持多种请求方式:
axios(config)
axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
安装:
cnpm install axios --save 项目实际运行也需要–save。
使用
- axios():
import axios from "axios"
axios({
url: "http://123.207.32.32:8000/home/multidata",
// 省略method参数,默认就是get请求
method: "get",
// params用于指定查询字符串
params: {
name: "abc"
}
}).then(res => {
console.log(res);
});
2. axios.all():
如果一次发送多个请求,等到都收到结果时再统一处理,可以使用axios.all([axios(), axios()…]), axios.all([]) 返回的结果是一个数组。
axios.all([
axios({url: "http://123.207.32.32:8000/home/multidata"}),
axios({
url: "http://123.207.32.32:8000/home/data",
params: {type: "sell", page: 1}
})
]).then((res1, res2) => {
console.log(res1);
console.log(res2);
});
-
axios的配置:
在开发中可能很多参数都是固定的,这个时候我们可以进行一些抽取,也可以利用axiox的全局配置。
其他配置信息见官网: http://www.axios-js.com/zh-cn/docs/// 全局配置 axios.defaults.baseURL = "http://123.207.32.32:8000"; axios.defaults.timeout = 5000; axios.defaults.headers = {'Content-Type': 'application/x-www-form-urlencoded'} axios.all([ axios({url: "/home/multidata"}), axios({ url: "/home/data", params: {type: "sell", page: 1} }) ]).then((res1, res2) => { console.log(res1); console.log(res2); });
-
axios实例:
从axios模块中导入对象时, 使用的实例是默认的实例。当给该实例设置一些默认配置时, 这些配置就被固定下来了。
但是后续开发中, 某些配置可能会不太一样。比如某些请求需要使用特定的baseURL或者timeout或者content-Type等。
这个时候,我们就可以创建新的实例,并且传入属于该实例的配置信息。
① 创建一个单独文件用于封装网络请求的框架,如果后续网络请求框架需要更换,只需要修改这一个文件即可。
② axios.create本身返回的就是promise;
-
拦截器:
应用场景:① 当发送网络请求时,页面显示loading动画;② 某些请求要求用户必须登录,判断用户时否携带token,如果没有token就跳转到login页面;③ 对请求参数进行序列化。
import axios from "axios"
export function httpService(data) {
const instance = axios.create({
baseURL: "http://123.207.32.32:8000",
timeout: 1000 * 10,
headers: {
"Content-Type": "application/json"
}
});
// 请求拦截
instance.interceptors.request.use(config => {
// 请求发送成功
console.log(config);
// 需要return拦截信息
return config
}, error => {
// 请求发送失败
console.log(error);
// 需要return拦截信息
return error
});
// 响应拦截
instance.interceptors.response.use( data=> {
// 请求响应成功
console.log(data);
// 需要return拦截信息
return data
}, error => {
// 请求响应失败
console.log(error);
// 需要return拦截信息
return error
});
return instance(data)
}
如下为请求发送成功拦截器信息: