store 存取数据数组对象_Vuex 在state中存取数据 modules分模块 (2018/11/28)

一、store是一个状态管理工具 (vueX中只有唯一 一个store)

用途 :存数据 取数据 改数据

把需要共享的数据放在store里 不需要共享的数据还是放在组件里

从state中取出数据渲染到view层------>view层再通过action改变数据------>action在将数据存入state  (vuex的处理流程是一个单向的数据流  必须先发动动作才能够改数据)

Vuex就是提供一个仓库,Store仓库里面放了很多对象。其中state就是数据源存放地,对应于与一般Vue对象里面的data(后面讲到的actions和mutations对应于methods)。

在使用Vuex的时候通常会创建Store实例new Vuex.store({state,getters,mutations,actions})有很多子模块的时候还会使用到modules。

总结,Store类就是存储数据和管理数据方法的仓库,实现方式是将数据和方法已对象形式传入其实例中。要注意一个应用或是项目中只能存在一个Store实例!!

Vuex 的思想是 当我们在页面上点击一个按钮,它会触发(dispatch)一个action, action 随后会执行(commit)一个mutation, mutation 立即会改变state,  state 改变以后,我们的页面会state 获取数据,页面发生了变化。 Store 对象,包含了我们谈到的所有内容,action, state, mutation,所以是核心了。

store 对象注入到根实例后,在所有的子组件中,就可以用this.$store 来指向store 对象,获取state。在子组件中,computed 属性是根据它的依赖自动更新的。所以只要store中的state发生变化,它就会自动变化。

通过computed属性可以获取到状态值,但是组件中每一个属性(如:count)都是函数,如果有10个,那么就要写10个函数,且重复写10遍return this.$store.state,不是很方便。vue 提供了 mapState 函数,它把state 直接映射到我们的组件中。

store就是一个实例其中存放了很多对象,每个对象又有不同的职责,有的存放数据,有的调用方法

建立新项目的步骤:

1、新建一个vue项目

2、把数据存到state里  在文件路径下 cnpm i  vuex  --save

3、启动项目  npm run dev

4、在src文件夹中新建一个文件夹  store---->index.js----->main.js引入store----->App.vue 取数据渲染到页面上

index.js (向store中存数据)

import  Vue from 'vue'  //引入两个插件

import Vuex from 'vuex'

Vue.use(Vuex)

var store = new Vuex.Store({ //向store中存入数据

state:{

n:1000,

age:12,

lessions:["java","html"], //数组

haha:{ //对象

yi:'mm'

}

}

})

export  default store //将数据暴露出去

main.js

import Vue from 'vue'

import App from './App'

import router from './router'

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

Vue.config.productionTip = false

new Vue({

el: '#app',

router,

store, //注册

components: {

App

},

template: ''

})

App.vue (从state中取数据)

{{n}}   {{age}}  {{lessions}}  {{haha}}   

export default {

name: 'App',

computed:{    //取数据

n(){

return this.$store.state.n

},

age(){

return this.$store.state.age

},

lessions(){

return this.$store.state.lessions[0]

},

haha(){

return this.$store.state.haha["yi"]

}

}

}

二、getters计算属性

Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

Getter 接受 state 作为其第一个参数, 也可以接受其他 getter 作为第二个参数

通过属性访问

Getter 会暴露为 store.getters 对象,你可以以属性的形式访问这些值

注意:getter 在通过属性访问时是作为 Vue 的响应式系统的一部分缓存其中的。(会产生缓存)

store.getters.doneTodos

通过方法访问

也可以通过让 getter 返回一个函数,来实现给 getter 传参。在你对 store 里的数组进行查询时非常有用。

注意,getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果。(不会产生缓存)

store.getters.getTodoById(2)

三、mutations 同步的方法更改数据

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。 唯一修改状态的事件的回调函数

mutation中放的是处理数据逻辑的方法,它能够使数据和视图分离,起到更改数据(状态)的作用。

(1)mutation 同步更改数据

每一个mutation都有一个字符串类型的事件类型(type)和回调函数(handler),先注册事件type,当触发响应类型的时候调用handler();

(2)payload   提交载荷

简单的理解就是往handler(state)中传参handler(state,payload);一般是个对象。

state      是存放数据的地方

payload      相当于一个参数

(3)commit   调用mutation中的type

可以在组件中使用 this.$store.commit.("type名") 提交 经过mutation操作后做出改动的数据

commit是同步函数,而且只能是同步执行

四、actions 异步的方法更改数据

Action 提交的是 mutation,而不是直接变更状态。并且可以包含任何的异步操作。actions将mutations里面只能同步处里数据的方法变成了可以异步处理数据的方法。

Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用context.commit来提交一个mutation(因为mutation中的type是通过 $store.commit方法被提交的,action中的mutation可以通过context.commit被提交 )

在组件中使用this.$store.dispatch("xxx") 分发 action

总结一下就是 同步提交mutation用 this.$store.commit("mutation中的type名")

异步提交mutation用 context.commit("mutation中的type名",参数)

异步分发action用 this.$store.dispatch("action中的type名")

store/index.js

import Vue from 'vue'

import Vuex from 'vuex'

import axios from 'axios'

Vue.use(Vuex)

var store = new Vuex.Store({

state:{  //存数据

n:10000,

age:12,

lesson:['aaaa','bbbbbb']

},

mutations:{ //同步的方法更改数据

changeAge1(state,payload){//type:changeAge1,handler的第一个参数是state;

state.age=state.age+1 // 变更状态

},

changeNum1(state,payload){ //  提交载荷 payload  简单的理解就是往handler(state)中传参handler(state,payload);一般是个对象。

state.n+=payload//这个payload相当于一个参数

},

addlesson(state,payload){

state.lesson=state.lesson.concat(payload) //在已有课程之后拼接新的课程 ②payload接收到了从actions中的getlesson中甩出来的数据

}

},

actions:{//异步的方法定义和调用数据

getlesson(context){ //context是自带的上下文对象

axios.get("http://localhost:3000/lessons").then((res)=>{//从data.json中获取数据

context.commit("addlesson",res.data.map((item)=>item.lesson))   //①第一个参数用于调用mutation中的方法  第二个参数相当于是payload 是将从json中获取到的值甩出去

})

}

}

})

export default store

App.vue

{{age}}  年龄

+{{n}}-

{{item}}

添加数据

export default {

name: 'App',

computed:{ //取数据

n(){

return this.$store.state.n

},

age(){

return this.$store.state.age

},

lesson(){

return this.$store.state.lesson

}

},

methods:{ //调用方法改变数据

changeAge(){

this.$store.commit("changeAge1")

},

changeNum(n){

this.$store.commit("changeNum1",n)

},

getlesson(){

this.$store.dispatch("getlesson")

}

}

}

五、modules分模块

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

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

操作步骤:

在src文件目录下新建一个store文件夹----->在store中新建一个index.js----->在store目录下新建一个demo文件夹 ------>在demo中新建state.js 、mutation.js、action.js、getter.js文件----->在demo/index文件中引入以上几个js文件,并将其暴露出去------>store/index 引入demo文件夹并且创建store实例 引入modules----->App.vue中调用方法----->main.js引入store中的index.js  注册store

state.js

export default{  //不需要写state:{}

n:1000,

age:12,

lesson:['math','english']

}

mutations.js

export default{

changeAge(state,payload){

state.age=state.age+1

},

changeNum(state,payload){

state.n+=payload

},

addlesson(state,payload){

state.lesson=state.lesson.concat(payload)

}

}

actions.js

import axios from 'axios'

export default{

getlesson(context){

axios.get("http://localhost:3000/lessons").then((res)=>{

context.commit('addlesson',res.data.map((item)=>item.lesson))

})

}

}

demo/index.js

import state from './state'

import mutations from './mutations'

import actions from './actions'

export default{

state,

mutations,

actions

}

store/index.js

import Vue from 'vue'

import Vuex from 'vuex'

import axios from 'axios'

import demo from './demo'

Vue.use(Vuex)

var store = new Vuex.Store({  //创建store实例

modules:{ //引入模块

demo

}

})

export default store

App.vue

+{{n}}+

改变年龄{{age}}

{{item}}

添加课程

export default {

name: 'App',

computed:{

n(){

return this.$store.state.demo.n  //注意路径

},

age(){

return this.$store.state.demo.age

},

lesson(){

return this.$store.state.demo.lesson

}

},

methods:{

changeAge(){

this.$store.commit('changeAge')

},

changeNum(inc){

this.$store.commit('changeNum',inc)

},

getlesson(){

this.$store.dispatch('getlesson')

}

}

}

main.js

import Vue from 'vue'

import App from './App'

import router from './router'

import store from '@/store/index'

Vue.config.productionTip = false

new Vue({

el: '#app',

router,  //把router和store放在实例上

store,

components: { App },

template: ''

})

六、四个辅助函数

mapstate      //将state中的数据映射到组件中去

mapmutations

mapactions

mapgetters

{{Counter.arr[idx]}}+

import {mapState,mapMutations} from ‘vuex’  //引入

computed:{

props:["idx"],

...mapState(["counter","arr"])   //这表示counter中的arr

},

mathods:{

...mapMutations(["inc"])

}


版权声明:本文为weixin_29029673原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。