How to use simple global store and axios in Vue project


引言

最近写的项目涉及组件间的通信,其中有一些资料是大部分组件都通用的,因此把它们抽取出来当成全局变量是最好的。在 Vue 项目中,state基本上意味着data,状态管理(State management)通常指应用层数据的管理。官方建议我们在小型应用中采用一个简单的store 模式即可。不幸的是,官方文档中的介绍过于简洁,而网上找到相关中文资料也很少,甚至出现用 store 模式实现 Vuex,天啦噜,这不就是把简单的问题复杂化了嘛。于是本文将要带领您如何使用简单的 store 模式。

创建 Vue 项目

首先使用 Vue Cli 创建一个 Vue 项目

vue create number-app

接下来会让你选择 dafault 或者 manual,我们选择 default 即可。

Vue CLI v4.4.6
? Please pick a preset: (Use arrow keys)
❯ default (babel, eslint)
  Manually select features

一旦项目创建完成,您需要进入项目中,然后运行该项目。

cd number-app
npm run serve

使用浏览器打开http://localhost:8080/,当你看到下图时表明项目已经成功跑起来了。

2020-10-26_number-app初始页面.png

不过我们接下来并不需要HelloWorld.vue,您可以把它和App.vue里相关部分删去。

store.js

src/文件夹下创建一个store.js文件,它将暴露一个store对象。

export const store = {
  state: {
    numbers: [1, 2, 3],
    text: ''
  },
  addNumber(newNumber) {
    this.state.numbers.push(newNumber);
  }
};

上面的numberstext是我们将要在多个组件中显示或操作的数据。需要注意,所有storestate的变更,都放置在store自身的action中去管理,addNumber(newNumber)便是一个范例。

在组件中使用

在组件中,我们需要import { store } from "../store.js";来引入store。在data中使用storeState: store.state来获取store中的state

现在我们创建一个NumberDisplay组件用来显示store中的数据。

<template>
  <div>
    <h2>{{ storeState.numbers }}</h2>
    <p>{{ storeState.text }}</p>
  </div>
</template>

<script>
import { store } from "../store.js";

export default {
  name: "NumberDisplay",
  data() {
    return {
      storeState: store.state
    };
  }
};
</script>

然后创建一个NumberSubmit组件用来添加新的数字到store中的number数组。使用store.addNumber来调用store中的addNumber,从而改变store中的state

<template>
  <div>
    <input v-model="numberInput" type="number" />
    <button @click="addNumber(numberInput)">
     Add new number
    </button>
  </div>
</template>

<script>
import { store } from "../store.js";

export default {
  name: "NumberSubmit",
  data() {
    return {
      numberInput: 0
    };
  },
  methods: {
    addNumber(numberInput) {
      store.addNumber(Number(numberInput));
    }
  }
};
</script>

现在您可以在页面上添加新的数字了。

2020-10-26_number-appv1.png

2020-10-26_number-app_add_number.png

使用 axios

有很多时候你在构建应用时需要访问一个 API 并展示其数据。做这件事的方法有好几种,而使用基于 promise 的 HTTP 客户端 axios 则是其中非常流行的一种。本文我们将使用Numbers API,它将返回一些有趣的文本给我们。

在 Vue 项目中使用 axios,首先

npm install --save axios vue-axios

然后在 main.js 中加上

import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'

Vue.use(VueAxios, axios)

这样您就可以在 Vue 文件中通过下面的三种方式来使用 axios:

Vue.axios.get(api).then((response) => {
  console.log(response.data)
})

this.axios.get(api).then((response) => {
  console.log(response.data)
})

this.$http.get(api).then((response) => {
  console.log(response.data)
})

但是当我在 store.js 文件中使用 axios 时却出现了错误Cannot read property 'get' of undefined

addNumber(newNumber) {
    this.state.numbers.push(newNumber);
    this.axios.get('http://numbersapi.com/'+ newNumber)
      .then(response => {
          this.state.text = response.data;
          console.log(response);
          })
  },

2020-10-26_使用axios报错.png

出错的原因是因为store.js文件中的this.axios并没有引用 Vue 实例,我们需要另外引入 axios。完整store.js文件如下:

const axios = require('axios');

export const store = {
  state: {
    numbers: [1, 2, 3],
    text: '3 is the number of spatial dimensions we perceive our universe to have.'
  },
  addNumber(newNumber) {
    this.state.numbers.push(newNumber);
    axios.get('http://numbersapi.com/'+ newNumber)
      .then(response => {
          this.state.text = response.data;
          console.log(response);
          })
  },
};

2020-10-26_number-app最终效果.png

至此,我们完成了 number-app。如果您的程序无法正常运行,请到 github 上查看源码

总结

通过本文,我们学会了如何在 Vue 项目中使用简单的状态管理 store,当您的项目足够简单时推荐您使用它而不是 Vuex。同时我们也接触了 axios,这是一个强大的工具。