35

小白带你学习Vuex

 5 years ago
source link: http://dopro.io/learn-vuex.html?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在做一些Vue项目时,如果遇到嵌套多层的组件间的数据同步和通信将会非常麻烦,另外如果一些数据交互是分散在各个组件的,很可能会重复获取数据,或者接口数据的返回有更改时,不能及时的定位,所以如果能在全局对数据进行统一的状态管理将会非常方便。 Vuex是Vue官方推荐的状态管理利器。

基础知识

BZ3AnmA.png!web

Vuex的官方文档( https://vuex.vuejs.org/zh/ )中有相应的阐述,以下是我的理解和整理。

  • state“状态”,整个应用只有一个state,为了确保对全局状态的管理,可以想象成一个大的“json对象”,也可以分为各个模块。
  • getter获取状态,进行数据请求
  • mutation修改状态的操作,同步
  • action提交mutation,异步简单来说,如果我们的state对象中有一个变量a的值为0;我们希望把a改为1,则需要进行的操作是先定义一个mutation将a置为1,然后用action去提交这个mutation,从而去修改state中的a。

开始实践

1.安装

npm i -g vue-cli    // 安装vue-cli
vue init webpack 项目名  // 初始化一个集成webpack的vue项目
npm i vuex    // 项目根目录下安装vuex

2.引入并使用Vuex,以及创建存储对象

import Vuex from 'vuex'
Vue.use(Vuex)

创建全局唯一的存储对象,命名随意,一般使用store,声明state对象,设置count为0;在mutations中使用add方法和minus方法更改count的值,mutation的参数一般是state对象和传入的参数;在actions中也有add和minus方法(actions中的函数的命名可以跟mutations中的一样)用于mutation的提交,参数一般是store对象和传入的参数。

const store = new Vuex.Store({
strict: true, // 严格模式——只能由mutation修改状态
state: {
  count: 0
},
mutations: {
  add (state, arg) {
   arg = arg || 1
   state.count += arg
},
  minus (state, arg) {
   arg = arg || 1
   state.count -= arg
}
},
actions: {
add ({commit}, arg) {
  commit('add', arg)
},
minus ({commit}, arg) {
  commit('minus', arg)
}
},
getters: {
}
})

最后需要把store对象挂载到Vue对象上。

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

3.在组件中使用store对象

前面我们已经准备好store对象,现在在组件中开始使用。我们写一个简单的父组件来显示count的值。

<template lang="html">
<span>{{state.count}}</span>
</template>

<script>
export default {
data () {
return {
  state: this.$store.state
}
}
}
</script>

然后我们在下面的子组件中改变count的值,Add方法中调用前面store中的action中的方法,用于提交更改,这样我们就简单实现了在一个组件中更改数据,在另一个组件中显示数据,其中的传参是为了在没有传值的时候加1和减1,在有参数的时候根据传参进行加减,这样就简单的使用了Vuex。

<template lang="html">
<li>
<input type="button" value="加1" @click="Add">
<input type="button" value="减1" @click="Minus">
</li>
</template>

<script>
export default {
data () {
return {
}
},
methods: {
Add () {
  this.$store.dispatch('add',3)
},
Minus () {
  this.$store.dispatch('minus',3)
}
}
}
</script>

那怎么把数据交互和Vuex配合起来呢? 我们来写一个demo实现从接口返回数据并显示在页面上。 写一个node server来模拟返回数据

const koa1=require('koa');
const router1=require('koa-router');

let server=new koa();
server.listen(8084);

server.use(async (ctx, next)=>{
ctx.set('Access-Control-Allow-Origin', '*');

await next();
});

let r1=router();

r1.get('/a', async ctx=>{
 ctx.body=[1,2,3,4,5,6];
});
server.use(r.routes());

在state中声明一个数组

state: {
    arr: []
}

在mutations中声明一个setArr方法用于更改arr的值

mutations: {
    setArr(state,arg){
        state.arr = arg;
    }
}

在actions中访问接口获取值

actions: {
    async getArr({commit},arg){
    let arr = await (await fetch('http://localhost:8084/server')).json();
    commit('setArr',arr);
    }
}

在getters中触发action(如果state中的arr不为空,则不会去请求数据)

getters: {
    arr(state){
    if(state.arr.length == 0){
    store.dispatch('getArr');
    }
    return state.arr;
    }
}

在组件中显示接口返回的值

<template>
<ul><li v-for="i in arr">{{i}}</li></ul>
</template>

<script>
export default {
data () {
return {
}
},
computed: {
arr () {
  return this.$store.getters.arr
}
},
}
</script>

这样就实现了vuex和数据交互的简单配合,可以在这个demo的基础上加以更改也可以跟上面的加以结合,实现前端触发更改传给后端的过程。

总结,Vuex的核心是store对象,我们在使用的时候需要先创建一个store对象(它是Vuex.Store对象的一个实例),然后在注册到Vue身上,就可以在组件里面使用了,在组件中的使用过程是,执行this.$store.dispatch方法,这个方法的作用是,找到对应的action,store对象中对应的action中会有一个commit方法去触发对应的mutation,只有mutation可以更改state对象的值,getters对象和actions对象配合使用可以进行数据交互。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK