咱们知道vue是组件式开发的,当你的项目愈来愈大后,每一个组件背后的数据也会变得愈来愈难以理顺,html
这个时候你就能够考虑使用vuex了。vue
备注: 官方建议小项目不要使用,引入vuex会带来新的概念和模式,这对于新手而言理解上自己有难度,并且小项目中vuex发挥的功效确实不怎么明显,vuex
反而增长了开发难度,就像后端项目中常说的 过分设计。vue-cli
说了这么多,下面介入正题(如下讲解须要一个空的vue项目,推荐使用 vue-cli 建立,快速搭建一个vue开发环境 ):后端
vuex的做用就是做为一个数据仓库(store),把多个组件的背后的数据都放到store中,而后全部组件经过约定的方式去读取数据和修改数据。网络
这一句话就归纳完了。没有想象的那么复杂。注意,这句话里面一个关键词叫 约定,下面来讲说有那些约定:app
在将约定以前,首先仍是要知道怎么定义一个仓库(store),进入项目而后 vue add vuex 。异步
经过这条命令,vue-cli 帮咱们建立了一个 store.js 的文件,并自动在根组件中引入了store,具体变化以下:ide
main.js 文件中自动变化了两处函数
import Vue from 'vue' import App from './App.vue' import store from './store' #【引入store文件】 Vue.config.productionTip = false new Vue({ store, #【在根组件中引入了store】 render: h => h(App) }).$mount('#app')
如今咱们编辑一下 store.js 文件:
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { user: { name: '张三', sex: '男' } }, mutations: { change_name (state,payload) { state.user.name = payload.new_name }, change_sex (state,payload) { state.user.sex = payload.new_sex } }, actions: { change_sex_by_action (context,payload) { setTimeout(() => { context.commit('change_sex',payload) },3000) } } })
理解:
state 是状态(数据中心)。
mutations 里面定义的函数用来修改state,mutation只能执行同步操做。
actions 的目的也是更改state,可是他不像mutation同样能够直接更改state,而是经过调用mutation来更改state。还有一个不一样点是,action能够执行异步操做,好比网络请求。
getters 返回组装DIY后的数据,好比state有个sex=“女”,经过getter在后面加一个 生 ,返回 女生,可是我以为把组件中 computed 干的事情放到store层不是一个好主意,因此本例中不涉及。
用法:
mutation的一个参数是 state,第二个参数是从 组件传过来的参数对象,
action的第一个参数是一个与 store 实例具备相同方法和属性的 context 对象,这句话有点难以理解,你就把context想象成一个新的store对象,
第二个参数仍是 组件传过来的参数对象
在编辑一下 App.vue 文件
<template> <div id="app"> <button @click="change_name">change name by mutation</button> <p>current name({{ user.name }})</p> <button @click="change_sex">change sex by action</button> <p>current sex({{ user.sex }})</p> </div> </template> <script> export default { data () { return { // user: this.$store.state.user } }, computed: { user() { return this.$store.state.user } }, methods: { change_name() { this.$store.commit({ type: 'change_name', new_name: '李四' }) }, change_sex() { this.$store.dispatch({ type: 'change_sex_by_action', new_sex: '女' }) } } } </script>
经过store获取数据都要放到computed里面,虽然在其余地方也能够直接获取,可是没法监听数据变更(就像上面注释的同样)。
change_name是经过mutation方式同步更改store中的数据,change_sex采用了action方式异步更改store中的数据。
若是在computed中须要获取的数据不少,可使用 官方提供的 mapState,具体用法查看官方 文档 。
我本身的理解:
不要滥用store,不要把全部的数据都放到store中,在组件化开发思想下,我认为组件和组件之间本就应该独立封装,
若是一个数据只有在某个组件中使用,而不须要被其余组件共享,那么最好不要放到其中,store只存储有必要的数据,不要让他变得太臃肿,不然麻烦早晚会来。
官方文档中说明,若是store太大能够采用模块方式分割,但貌似不太优雅,
最后我仍是推荐store只放必要的东西,不要让他变得太肥胖。