Vuejs学习七:vuex、axios

vuex、axios

1 Vuex

针对Vue.js应用程序开发的状态管理模式,说白了就是:组件之间有些状态(简单理解为变量变量)希望互相共享,如果按照原来的父子组件传递,那就很麻烦,于是状态管理工具就应运而生。

Vuex就是组件共享数据的管家,放进去的状态是响应式的。

1.1 简单使用

安装vuex后会出来一个store文件夹,里面的index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  //保存状态
  state: {
    counter:1000
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})

如果我们想使用state里的状态,在vue文件的template中

<template>
  <div>
    <h2>{{$store.state.counter}}</h2>
  </div>
</template>

如果我们想改state,可以这样

<div>
    <h2>{{$store.state.counter}}</h2>
    <button @click="$store.state.counter++">+</button>
    <button @click="$store.state.counter--">-</button>
  </div>

但是vue官方不推荐这样直接改,因为这样修改会绕过vue的官方浏览器插件devtools,无法在开发中对vuex的状态进行监听。那么我们要怎么做呢?

首先我们修改vuex的index.js

  //保存状态
  state: {
    counter:1000
  },
  mutations: {
    increment(state){
      state.counter++
    },
    decrement(state){
      state.counter--
    },
  },
  actions: {
  },
  modules: {
  }

在mutations中注册相关方法(如果是异步网络请求需要先在actions中进行,再调用mutation中的方法修改)

然后再vue文件中通过commit来使用方法

<template>
  <div>
    <h2>{{$store.state.counter}}</h2>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
  </div>
</template>

<script>
  export default {
    name: "HelloVUe",
    methods:{
      increment(){
        return this.$store.commit('increment')
      },
      decrement(){
        return this.$store.commit('decrement')
      },
    }
  }
</script>

然后在浏览器就可以通过devtools来观察state的变化,可以看到每一步操作后state的变化。

在这里插入图片描述

1.2 Vuex核心概念

1.2.1 state单一状态树

单一状态树就是单一数据源,vue推荐把多个组件涉及到的状态管理为单一数据源。

1.2.2 getters

类似于计算属性

index.js中

  getters:{
    powerCounter(state){
      return state.counter*state.counter
    }
  }

template:

   <h2>getters使用</h2>
   <h3>{{$store.getters.powerCounter}}</h3>

getters下的函数,第一个参数为state第二个为getters,所以我们可以在getters中利用其他getters

getters:{
    powerCounter(state,getters){
      return state.counter*state.counter
    }
    //平方之后+1
     powerCounterPlus1(state,getters){
      return powerCounter+1
    }
  }

如果我们希望用户使用getters时候可以传入一些参数要怎么做呢?利用回调函数传入参数

  getters:{
      //返回counter*自定义参数para
    powerCounter(state){
      return function(para){
          return state.counter*para
      }
    }
  }

1.2.3 mutation

mutation中可以传递额外的参数(可以是对象):

mutations:{
    powerCounter(state,n){
      return state.counter*n
    }
  }

除了commit方法提交,vue还提供了对象提交风格。以对象提交后,mutations中以对象接收输入的参数

//vue methods对象方式提交
decrement(){
        return this.$store.commit({
          type:'decrement',
          count:1,
          aaa:2
        })
      }
//vuex index.js中
decrement(state,payload){
      console.log(payload);
    //type: "decrement", count: 1, aaa: 2
      state.counter--
    }

响应式规则:vue中的响应式不是万能的,如果你在已经确定好属性的对象中添加新的属性,vue默认是不会执行响应式的。如何解决呢?

使用vue的set方法

Vue.set(state.obj,'key','value')
Vue.delete(state.obj,'key')//响应式删除属性
  • mutation常量

    我们一般会把mutation绑定的函数名作为常量进行导入

    创建mutation常量池:mutation-type.js

    export const INCREMENT="increment"

    在vuex中导入并使用

    import * as mutationsType from './mutations-type'
    ...
     mutations: {
        [mutationsType.INCREMENT](state){
          state.counter++
        },
    ...

    vue文件中使用

    import * as mutationsType from '../store/mutations-type'
    export default {
      name: "HelloVUe",
      methods:{
        increment(){
           return this.$store.commit(mutationsType.INCREMENT)
          },
     ...

1.2.4 Actions

vuex要求我们不要在mutation中写异步操作,因为devtools还是无法追踪。我们需要使用Action,但是不能直接在Action中执行具体的操作,必须还是要通过mutations进行提交

  • 首先在actions中定义异步操作(下例中aIncrement)
  • 在异步操作中提交mutations的方法
  • 在vue文件中通过dispatch(分发)实现异步操作
actions: {
    //上下文对象
    aIncrement(context){
      //异步操作
      setTimeout(()=>{
        context.commit('increment')
      },1000)
    }
  },

vue文件

methods:{
      increment(){
       this.$store.dispatch('aIncrement')
      },

Actions可以联合Promise使用,index的Actions中

 double(context) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          context.commit('double')
          resolve("异步请求完毕")
        }, 1000)
      })
    },

vue文件中

  double() {
        // this.$store.dispatch('double')执行Actions中的double方法,返回Promise对象
        this.$store.dispatch('double').then(res => console.log(res))
      }

1.2.5 Modules

vuex提供的单一状态树会导致状态较为臃肿,所以vuex提供了modules来管理这些vuex,每一个modules都可以包含自己的actions、mutations、getters、states

const ModuleA={
  state:{
    id:1,
    name:'zhangsan'
  },
  mutations:{},
  actions:{},
  getters:{}
};

...
	modules: {
    a:ModuleA
  }
})

使用,a这个module的state会放到$store的state中

<h2>modules使用</h2>
<h3>{{$store.state.a.name}}</h3>

模块中的getters有第三个属性rootState,这个属性可以访问store的state

getters:{
    getter1(state,getters,rootState){
      console.log(rootState.counter);
    }
  }

模块中的actions的commit只能调用自己模块中的东西

1.2.6 vuex目录结构

我们可以把vuex的getters mutations actions modules都抽取为单独的js,通过导入来管理

index.js就变成这样

import Vue from 'vue'
import Vuex from 'vuex'
import {mutations} from "./mutations"
import {actions} from "./actions";
import {getters} from "./getters";
import {ModuleA} from "./modules/moduleA";

Vue.use(Vuex)

const state = {
  state: {
    counter: 1000
  },
}
export default new Vuex.Store({
  state,
  mutations,
  actions,
  getters,
  modules: {
    a: ModuleA
  }
})

2 axios

2.1 基本使用

params会自动作为get请求中的参数进行拼接

axios({
  url:'https://httpbin.org/get'
}).then(res=>{
  console.log(res);
})
axios({
  url:'https://httpbin.org/home/data',
  params:{
    type:'pop',
    page:1
  }
}).then(res=>{
  console.log(res);
})
//2. 并发请求
axios.all([axios({
  url: ""
}), axios({
  url: ""
})]).then((res) => {

});

2.2 配置

axios.defaults.baseURL="https://httpbin.org";//默认地址路径
axios.defaults.timeout=5000;//超时时间

axios({
  url: '/get'
    ...

但是开发里一般不用全局的,通过创建一个axios实例进行处理

const instance1 = axios.create({
  baseURL: "https://httpbin.org",
  timeout: 5000//超时时间
});
instance1({
  url: ''
}).then(() => {
})

2.3 拦截器

通过设置请求拦截器和响应拦截器,对请求进行预处理或是对响应数据进行预处理

import axios from 'axios'
export function request(config) {
  //1.创建axios实例
  const instance=axios.create({
    baseURL:'http://123.207.32.32:8000/api/v1',
    timeout:1000000
  });
  //请求拦截
  instance.interceptors.request.use((config)=>{
    console.log(config);//config为网络请求的信息配置,拦截器就可以对请求做一些限定
    return config;//这里必须返回,否则会被拦截掉
  },(error)=>{
    console.log(error)
  })
  //响应拦截 拦截成功和拦截失败
  instance.interceptors.response.use((res)=>{
    console.log(config);
    return res.data;
  },(error)=>{
    console.log(error)
  })
  return instance(config)//Promise对象
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值