一、什么是Vuethis.$store
Vuethis.$store是Vue.js提供的状态管理模式,它可以让我们在Vue.js应用中进行集中式状态管理。Vuex将状态抽取出来,单独管理,以便于实现数据共享和数据维护。
二、Vuethis.$store的使用场景
Vuex通常用于大型单页面应用(SPA),其中数据流比较复杂而且数据量比较大的应用。对于一些简单的应用,单独使用Vuethis.$store可能会使得应用过度复杂。
三、Vuethis.$store的核心概念
1、state
state是Vuethis.$store的数据中心,即包含多个属性的对象。
state: { count: 0 }
2、mutation
mutation是Vuethis.$store中用于修改state的唯一途径,它类似于事件,每个mutation都有一个字符串类型的事件类型和一个回调函数。
mutations: { increment(state) { state.count++ } }
3、getter
getter与state类似,也是一个函数,它用于获取某些状态的值并做出响应操作。
getters: { getCount: state => { return state.count } }
4、action
actions是用于处理异步操作的方法。其传递给mutations的是mutation的payload。
actions: { incrementAsync({ commit }, payload) { setTimeout(() => { commit('increment', payload) }, 1000) } }
四、Vuethis.$store的使用方法
1、安装Vuex
使用npm安装Vuex或者直接引入CDN都可以。
npm install vuex --save
2、创建一个store
在Vue.js应用的入口文件(main.js)中引入Vue和Vuex并实例化store。
import Vue from 'vue' import Vuex from 'vuex' import App from './App.vue' Vue.use(Vuex) const store = new Vuex.Store({ state: { count: 0 }, mutations:{ increment (state) { state.count++ } }, getters: { getCount: state => { return state.count } }, actions: { incrementAsync({ commit }, payload) { setTimeout(() => { commit('increment', payload) }, 1000) } } }) new Vue({ render: h => h(App), store: store }).$mount("#app")
3、Vuethis.$store的使用
在具体的Vue组件中访问Vuethis.$store可以用$store属性。
<template> <div> <p>Count: {{ count }}</p> <button v-on:click="add">增加</button> </div> </template> <script> export default { name: 'About', computed: { count () { return this.$store.getters.getCount } }, methods: { add () { this.$store.commit('increment') } } } </script>
五、Vuethis.$store的使用案例
下面是一个根据GitHub API获取GitHub用户信息并展示的案例。
1、Vuex store.js
import axios from 'axios' export default new Vuex.Store({ state: { user: null, repositories: [], followers: [], following: [], loading: false, }, mutations: { setUser(state, user) { state.user = user }, setRepositories(state, repos) { state.repositories = repos }, setFollowers(state, followers) { state.followers = followers }, setFollowing(state, following) { state.following = following }, setLoading(state, loading) { state.loading = loading }, }, actions: { async fetchUser({ commit }, username) { commit('setLoading', true) const { data: user } = await axios.get(`https://api.github.com/users/${username}`) commit('setUser', user) commit('setLoading', false) }, async fetchRepositories({ commit }, username) { commit('setLoading', true) const { data: repos } = await axios.get(`https://api.github.com/users/${username}/repos`) commit('setRepositories', repos) commit('setLoading', false) }, async fetchFollowers({ commit }, username) { commit('setLoading', true) const { data: followers } = await axios.get(`https://api.github.com/users/${username}/followers`) commit('setFollowers', followers) commit('setLoading', false) }, async fetchFollowing({ commit }, username) { commit('setLoading', true) const { data: following } = await axios.get(`https://api.github.com/users/${username}/following`) commit('setFollowing', following) commit('setLoading', false) }, }, getters: { getUser(state) { return state.user }, getRepositories(state) { return state.repositories }, getFollowers(state) { return state.followers }, getFollowing(state) { return state.following }, getLoading(state) { return state.loading }, } })
2、App.vue
<template> <div id="app"> <input type="text" v-model="username" placeholder="GitHub username" /> <button v-on:click="getUserData">查询</button> <div v-if="loading">Loading...</div> <div v-else-if="user"> <h2>{{ user.login }}</h2> <p>{{ user.bio }}</p> <p>followers: {{ user.followers }}, following: {{ user.following }}, public repos: {{ user.public_repos }}</p> </div> <div v-if="loading">Loading...</div> <div v-else-if="repositories"> <h3>Repositories</h3> <ul> <li v-for="repo in repositories" :key="repo.id"> <a :href="repo.html_url" target="_blank">{{ repo.full_name }}</a> </li> </ul> </div> <div v-if="loading">Loading...</div> <div v-else-if="followers"> <h3>Followers</h3> <ul> <li v-for="follower in followers" :key="follower.id"> <a :href="follower.html_url" target="_blank">{{ follower.login }}</a> </li> </ul> </div> <div v-if="loading">Loading...</div> <div v-else-if="following"> <h3>Following</h3> <ul> <li v-for="follow in following" :key="follow.id"> <a :href="follow.html_url" target="_blank">{{ follow.login }}</a> </li> </ul> </div> </div> </template> <script> import { mapActions, mapGetters } from 'vuex' export default { name: 'App', data() { return { username: '' } }, computed: { ...mapGetters(['getUser', 'getRepositories', 'getFollowers', 'getFollowing', 'getLoading']), user() { return this.getUser }, repositories() { return this.getRepositories }, followers() { return this.getFollowers }, following() { return this.getFollowing }, loading() { return this.getLoading }, }, methods: { ...mapActions(['fetchUser', 'fetchRepositories', 'fetchFollowers', 'fetchFollowing']), async getUserData() { this.$store.commit('setUser', null) this.$store.commit('setRepositories', []) this.$store.commit('setFollowers', []) this.$store.commit('setFollowing', []) const username = this.username await Promise.all([ this.fetchUser(username), this.fetchRepositories(username), this.fetchFollowers(username), this.fetchFollowing(username) ]) } } } </script>