vuex 和 axios

@(js学习笔记)

vuex

vuex介绍

vuex官网

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态

配合插件

vue devtools

安装vuex

安装模块
npm install vuex --save

使用插件
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

定义
new Vuex.Store()

注入vue实例
store


vuex核心概念

store

1.页面中只能存在一个
2.状态响应
3.状态更改需要提交mutation

let store = new Vuex.Store({
	state:{},
	getters:{},
	...
})

export default store

state

包含了全部的应用层级状态

 state: {
    a: 1,
    b: 2
  }
  
  //组件中使用
  computed: {
     num(){
     return this.$store.state.a
     },
     num2(){
     return this.$store.state.b
     },
   }

获取多个状态时候,可以使用mapState辅助函数简化操作

getters

store的计算属性
Getters 接受 state 作为其第一个参数
Getters 会暴露为store.getters对象

getters: {
    a(state){
      return ...
    }
  }

//组件中使用
this.$store.getters.a

mutations

使用

更改 Vuex 的 store 中的状态的唯一方法
mutation 必须是同步函数

state: {
    num: 1
  },
  mutations: {
    addNum (state) {
      // 变更状态
      state.num++
    }
  }
  
//组件中调用
this.$store.commit('addNum')
提交Payload
  mutations: {
    addNum (state,payload) {
      // 变更状态
      state.num+=payload.newNum
    }
  }  
  
//组件中调用
this.$store.commit('addNum',{
newNum:3
})
//或
this.$store.commit({
type:'addNum',
newNum:3
})
//也可以传单个参数
this.$store.commit('addNum', 10)
//接收时用形参直接使用

actions

Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。

state: {
    num: 1
  },
  mutations: {
    addNum (state) {
      // 变更状态
      state.num++
    }
  },
  actions: {
    asyncAdd(context){
      setTimeout(function () {
          context.commit('addNum', {n: 5});
        },1000);
        context.dispatch('newCs', 'cs')
    },
    newCs(context, obj){
      console.log(obj) //cs
    }
  }
  
//组件中调用
this.$store.dispatch('asyncAdd');

辅助函数

引入
import {mapState,mapGetters,mapActions,mapMutations} from 'vuex'

mapState

获取多个状态时候,可以使用mapState辅助函数简化操作

 state: {
    a: 1,
    b: 2,
    c: 3
  }
  
  //组件中使用
	//计算属性的名称与state状态名称一样,可以给mapState传一个字符串数组
	//###1
    computed:{
      ...mapState(['a','b','c'])  //扩展运算
    }

	//###2
	computed: mapState(['a','b','c'])

	//###3
	computed: mapState({
      //###3-1 
      a: state => state.a
	  //###3-2
      b: 'b'
      //###3-3
      c(state){
        return state.c
      }
    })

mapGetters

将 store 中的 getters 映射到局部计算属性

getters: {
    a(state){
      return ...
    }
  }

//组件中使用
computed:{
	...mapGetters({
	    num:'a'
	 })
 }

mapMutations

methods: {
	...mapMutations({
	  a:'addNum'
	})
}

mapActions

methods: {
	...mapActions({
	   a:'asyncAdd'
	 })
 }

Modules

Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块

let newModule = {
  state: {
	  num:1
  }
  /* ... */
}

//实例中添加
let store = new Vuex.Store({
  modules:{
    newModule
  }
})

//组件中使用
this.$store.state.newModule.num

为了便于维护可以用不同的js文件区别不同的Modules

//Modules文件
let newModule = {
  state: {
	  num:1
  }
  /* ... */
}
export default newModule

//在根实例文件中添加
import newModule from './newModule'

let store = new Vuex.Store({
  modules:{
    newModule
  }
})

axios

介绍

浏览器支持
如果你的浏览器环境不支持 ES6 Promise,你可以使用 polyfill

基于 Promise 可用于浏览器和 Node.js
特征

  • 支持 promise API
  • 拦截请求
  • 在浏览器中发送 XMLHttpRequests 请求
  • 拦截请求和响应
  • 转换请求和响应数据
  • 自动转换 JSON 数据

安装
$ npm install axios

使用

在模块中引入
import axios from 'axios'

支持的请求方式

  • 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]])

例-get,post

get

//普通请求数据
axios.get('url')
  .then((response)=>{
      console.log(response)
  })
  .catch((error) =>{
       console.log(error)
   })

//带参数
axios.get('/user', {
    params: {
      ID: 123
    }
  })
  .then((response)=>{
      console.log(response)
  })
  .catch((error) =>{
       console.log(error)
   })

post

axios.post('/user', {
      ID: 123
  })
  .then((response)=>{
      console.log(response)
  })
  .catch((error) =>{
       console.log(error)
   })

例-并发请求

语法
axios.all(iterable)
axios.spread(callback)

    function http1(){
      return axios.get("url")
    }

    function http2(){
      return axios.get("url")
    }

    axios.all([http1(),http2()])
      .then(axios.spread((res1,res2)=>{
          console.log(res1)
          console.log(res2)
      }))
      .catch((error) =>{
        console.log(error)
    })

自定义请求

创建
axios.create(config)

配置信息

axios.create({
    baseURL:'', //接口
    timeout: 1000, //超时时间
    responseType:'json', //返回数据类型
    headers:{},  //请求头信息
    params{},  //参数
    transformRequest[function (data) {return data;}],  //发送请求之前对请求数据做处理
    transformResponse:[function (data) {return data;}], //提前处理返回的数据
    validateStatus:function(status){
	     return status < 400;
    }, //定义对于给定的HTTP 响应状态码是(根据返回值判断) resolve 或 reject
    cancelToken:source.token //指定用于取消请求的 cancel token
})

//###注:transformRequest 可以使用 queryString模块
cancelToken取消请求

创建
var CancelToken = axios.CancelToken;
var source = CancelToken.source();

配置
cancelToken:source.token

捕获取消错误
if (axios.isCancel(thrown)) { console.log('Request canceled', thrown.message); } else { console.log(error) }

取消请求 -- message 参数是可选的
source.cancel('取消')

例子
import axios from 'axios'
var CancelToken = axios.CancelToken;
var source = CancelToken.source();

var HTTP = axios.create({
  baseURL: 'url',
  timeout: 1000,
  cancelToken: source.token
})


HTTP.post("url")
  .then((response) => {
    console.log(response)
  })
  .catch((error) => {
    if (axios.isCancel(error)) {
      console.log(error.message);
    } else {
      console.log(error)
    }
  })

source.cancel('取消')


拦截器

在请求或响应被 then 或 catch 处理前拦截它们

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    return response;
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });

取消拦截

var myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);

在vue中使用axios

在组件中使用
引入后正常使用
import axios from 'axios';

注册为全局的函数
在入口文件main.js文件中引入

import Axios from 'axios'
import VueAxios from 'vue-axios'

Vue.use(VueAxios,Axios)

//之后在组件中使用
this.$http.get('url')
  .then((response) => {
    console.log(response)
  })
  .catch((error) => {
    console.log(error)