Vue-vuex

官方解释

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。

1.什么是状态?

状态这里泛指 vue 组件的一些当前的状况和性质,例如开发音乐播放器时,当前的播放状态是暂停、播放或者播放模式是列表循环、单曲循环,顺序播放等。

2.状态管理是什么:

状态管理是对之前说的状态进行管理,例如 a 组件这个状态需要通知 b 组件,或者 b 组件的当前状态需要触发 b 的父组件的某个属性。

具体有以下三个内容:

state,驱动应用的数据源;
view,以声明方式将 state 映射到视图;
actions,响应在 view 上的用户输入导致的状态变化


Vuex的核心

state
getters
mutations
actions
module

1.State

1)单一状态树

Vuex使用单一状态树--是的,用一个对象就包含了全部的应用层级状态。至此它便作为一个『唯一数据源(SSOT)』而存在。这也意味着,每个应用将仅仅包含一个store实例。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。

2)在Vue组件中获得Vuex状态

最好在根实例中注册store选项,该store实例会注入到根组件下的所有子组件中,且子组件能通过this.$store访问到。而不是在每个需要使用state的组件中需要频繁地导入。

3)mapState辅助函数

当一个组件需要获取多个状态时候,可以使用mapState辅助函数帮助我们生成计算属性,这样可以简化代码书写。mapState函数会返回一个对象,然后可以使用对象展开运算符将它与局部计算属性混合使用。

4)不要滥用vuex

使用Vuex并不意味着你需要将所有的状态放入Vuex。虽然将所有的状态放到Vuex会使状态变化更显式和易调试,但也会使代码变得冗长和不直观。如果有些状态严格属于单个组件,最好还是作为组件的局部状态。你应该根据你的应用开发需要进行权衡和确定。

2.Getters

getters用来从store中的state中派生出一些状态,例如对列表进行过滤并计数

getters可以认为是store的计算属性。和state类似,有mapGetters辅助函数。

所以getters的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

3. Mutations

更改Vuex的store中的状态的唯一方法是提交mutation。Vuex中的mutations非常类似于事件:每个mutation都有一个字符串的事件类型(type)和一个回调函数(handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受state作为第一个参数

1)提交载荷(Payload)

你可以向store.commit传入额外的参数,即mutation的载荷(payload):

2)Mutations需遵守Vue的响应规则

3)使用常量替代Mutation事件类型

4)mutation必须是同步函数

5)在组件中提交Mutations

你可以在组件中使用this.$store.commit('xxx')提交mutation,或者使用mapMutations辅助函数将组件中的methods映射为store.commit调用(需要在根节点注入store)。

4. Actions

actions类似于mutation,不同在于:

actions提交的是mutation,而不是直接变更状态。

actions可以包含任意异步操作。

1)在组件中分发Action

你在组件中使用this.$store.dispatch('xxx')分发action,或者使用mapActions辅助函数将组件的methods映射为store.dispatch调用(需要先在根节点注入store)

2)组合Actions

Action通常是异步的,那么如何知道action什么时候结束呢?更重要的是,我们如何才能组合多个action,以处理更加复杂的异步流程?

首先,你需要明白store.dispatch可以处理被触发的action的回调函数返回的Promise,并且store.dispatch仍旧返回Promise。

5. Modules

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store对象就有可能变得相当臃肿。

为了解决以上问题,Vuex允许我们将store分割成模块(module)。每个模块拥有自己的state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割。

vuex 配合 axios 开发(案例)

1.安装vuex

npm install vuex --save复制代码

2.安装axios

npm install axios --save复制代码

3.创建目录结构


main.js

import store from './store/index'  //引入store

new Vue({
    el: '#app',
    router,
    store,
    components: { App },
    template: '<App/>'
})
复制代码

注:以上代码在项目的vue初始化的时候引用并初始化,每一个vuex的核心就是一个store(仓库)。store相对于是一个容器,里面存放着你的项目中的大部分的状态。Vuex通过store选项,提供了一种机制将状态从根组件注入到每一个子组件中。通过这种注入机制,就能在子组件...vue 通过this.$store访问:

store/index.js  

//我们组装模块并导出 store 的地方

import Vue from 'vue'
import Vuex from 'vuex'
import movieList from './modules/movieList'
Vue.use(Vuex);

export default new Vuex.Store({
	modules: {
		movieList
	}
})复制代码

注:以上代码导入了vue和vuex模块,然后注册使用vuex,最后导出一个vuex的实例 

store/modules/movieList.js

import * as types from '../mutation-types'
import movie from '../../api/movie'

const state = {
	list: []
}

const getters = {
	list: state => state.list //获取当前的list
}

const actions = {
	// 获取正在上映的电影
  	getInTheaters({ commit }){
	    movie.getInTheatersMovie().then(data => {
	      	commit(types.MOVIE_LIST, data)
	    })
  	}
}

const mutations = {
	[types.MOVIE_LIST](state, data){
	    state.list = data.subjects; //改变当前的list
	}
}

export default {
	state,
	getters,
	actions,
	mutations
}复制代码

store/mutation-types.js

export const MOVIE_LIST = 'MOVIE_LIST' // 电影列表复制代码

注:mutation-types:将常量放在单独的文件中,方便协作开发。

api/movie.js

import axios from 'axios'
export default {
  	// 获取电影列表信息
  	getInTheatersMovie(start = 0, count = 18){
    	    return this.reqUrl(`/api/movie/in_theaters?start=${start}&count=${count}`)
  	},
  	// axios 请求
  	reqUrl(url){
	    return new Promise((resolve, reject) => {
	      	axios.get(url).then(response => {
	        	resolve(response.data);
	      	})
	    })
  	}
}复制代码

组件中使用 ...vue

    import {mapGetters, mapActions} from 'vuex'
    export default {
        computed: mapGetters({
            list: 'list'
        }),
        methods: mapActions([
             'searchMovie'
        ]),
        mounted() {
            this.$store.dispatch('getInTheaters'); //分发
        }
    }复制代码

注:你在组件中使用 this.$store.dispatch('xxx') 分发 action,或者使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用(需要先在根节点注入 store):


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值