vuex的使用笔记

6

vuex作为vue的扩展,功能更加的强大,经过几天的摸索,我才逐步掌握,接下来给大家从头到尾详细分析一波: 首先我们安装vuex,我使用的是vue-cli脚手架工具进行配置使用: …

vuex作为vue的扩展,功能更加的强大,经过几天的摸索,我才逐步掌握,接下来给大家从头到尾详细分析一波:

首先我们安装vuex,我使用的是vue-cli脚手架工具进行配置使用:

1.基本操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//第一步  安装
vue init webpack vuex     (拓展插件我只选择了路由【router】)
npm install vuex --save

//第二步 新建文件夹store,在里面新建index.js文件接下来引入
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//定义一个容器
let store = new Vuex.Store({})
export default store

//第三步 在main.js中也要引入store文件
import store from "./store"

2.对vuex的基本使用,使用vuex进行数据渲染

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//第一步 在store文件夹中的index.js中写上  表明我们定义的数字是100
let store = new Vuex.Store({
 state:{
    count:100
 }

//第二步 在视图对应的组件中我们使用vue中的计算属性对数据进行渲染
<template>
<div>
<h2>简易加法计算器</h2>
<div>
  <input type="button" value="-" />
  <span>{{num}}</span>
  <input type="button" value="+" />
</div>

</div>

</template>
<script>
  export default {
    computed:{
      num(){
        //拿到vuex中的值
              console.log(this.$store.state.count);
              return this.$store.state.count;
      }
</script>

//现在值是已经可以显示了,为100

3.添加事件,对数据可以进行加减操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//第一步 在视图对应的组件中添加事件
<template>
<div>
<h2>简易加法计算器</h2>
<div>
  <input type="button" value="-" @click="deHandle"/>
  <span>{{num}}</span>
  <input type="button" value="+" @click="addHandle"/>
</div>

</div>

</template>
<script>
  export default {
    computed:{
      num(){
        //拿到vuex的值
        console.log(this.$store.state.count);
        return this.$store.state.count;
      },

    },
    methods:{
      addHandle(){
 //改变状态,提交mutation addIncrement会提交过去 ,下面的含义表示的是触发vuex中定义的事件addIncrement,mutation提交不应该有异步操作的数据
        this.$store.commit("addIncrement")
      },
      deHandle(){
        this.$store.commit("deIncrement")
      }
    }
  }

</script>


//第二步 在store中的index.js中进行判定(有事件捕获的感觉)
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

//定义一个容器
let store = new Vuex.Store({
 state:{
    count:100
 },
mutations:{
        //state是一个默认的参数,
    addIncrement(state){
        state.count+=1;
    },
    deIncrement(state){
        state.count-=1;
    }
}
})
export default store

//到这里,一个使用vuex实现加减的效果就实现了

注意:

改变状态,提交mutation addIncrement会提交过去 ,下面的含义表示的是触发vuex中定义的事件

注意:以上为vue-cli2.0版本的,下面为3.0版本的,个人认为3.0的比2.0的要简单一些

简单的加减

1、编写组件,搭建路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//router
export default new Router({
  //mode: 'history', //没有#模式
  routes: [{
      path: '/',
      name: 'data',
      component: data
    }

  ]
})

//template
<template>
  <div>
    <button @click="handleIncrement">增加</button>
    <input type="number"
           @change="changes"
           v-model="count">
    <button @click="handleDecrease">减少</button>

  </div>

</template>
<script>
export default {
  data () {
    return {
    }
  },
  methods: {
    //监听数据的呀
    changes () {
      console.log(1);
    },
    handleIncrement () {
      this.$store.commit('increment');
    },
    handleDecrease () {
      this.$store.commit('decrease');
    }
  },
  computed: {
    count () {
      return this.$store.state.count
    }
  }

}
</script>

//app.vue
<template>
  <div id="app">
    <router-link to="/">vuex数据展示</router-link>
    <router-view/>
  </div>
</template>

2、在store中的mutations编写代码实现加加减减的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
export default new Vuex.Store({
  state: {
    count: 0
  },
  mutations: { //this.$store.commit('方法的名称','按需传入唯一的参数')
    increment(state) {
      state.count++
    },
    decrease(state) {
      state.count--
    }
  },
  getters: { //this.$store.getters.***

  }
})

3、在dada.vue组件中使用commit调用加减函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<template>
  <div>
    <button @click="handleIncrement">增加</button>
    <input type="number"
           @change="changes"
           v-model="count">
    <button @click="handleDecrease">减少</button>

  </div>

</template>
<script>
export default {
  data () {
    return {
    }
  },
  methods: {
    //监听数据的呀
    changes () {
      console.log(1);
    },
    handleIncrement () {
      this.$store.commit('increment');
    },
    handleDecrease () {
      this.$store.commit('decrease');
    }
  },
  computed: {
    count () {
      return this.$store.state.count
    }
  }

}
</script>
注意:使用this.$store.state.count可以直接在任何组件中获取到改属性的值

使用vuex获取数据进行过滤操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//在store中定义数据为 list:
export default new Vuex.Store({
  state: {
    list: [1, 5, 8, 10, 30, 50]
  }
  }
})

//在data.vue组件中定义
<template>
  <div>
    {{list}}
  </div>

</template>
<script>
export default {
  data () {
    return {
    }
  },
  methods: {
  },
  computed: {
    list () {
      return this.$store.state.list.filter(item => item < 10);

    }
  }

}
</script>
但问题在于,如果还有其他的组件也需要过滤后的数据时,就得把computed的代码完全复制一份,并且需要修改过滤方法时,每个用到的组件都得修改,如果能够将computed的方法也提取出来就方便很多了,getters就是用来做这个事的

使用getters来对数据进行筛选(filter)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//在store中定义数据为 list:
export default new Vuex.Store({
  state: {
    list: [1, 5, 8, 10, 30, 50]
  },
  getters: { //this.$store.getters.***
    filteredList: state => {
      return state.list.filter(item => item < 10)
    }

  }
  }
})

//在data.vue组件中定义
<template>
  <div>
    {{list}}
  </div>

</template>
<script>
export default {
  data () {
    return {
    }
  },
  methods: {
  },
  computed: {
    list () {
            return this.$store.getters.filteredList;
    }
  }

}
</script>
这种用法与组件的计算属性非常的像。getter也可以依赖其他的getter,把getter作为第二次参数,比如在写一个getter,计算出list过滤后的结果的数量

这种用法与组件的计算属性非常的像。getter也可以依赖其他的getter,把getter作为第二次参数,比如在写一个getter,计算出list过滤后的结果的数量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//store中
  getters: { //this.$store.getters.***

    filteredList: state => {
      return state.list.filter(item => item < 10)
    },
    listCount: (state, getters) => {
      return getters.filteredList.length;
    }
  }
//data.vue中



<template>
  <div>
    {{list}}
    {{listCount }}
  </div>

</template>
<script>
export default {
  data () {
    return {
    }
  },
  methods: {
  },
  computed: {
    list () {
      return this.$store.state.list.filter(item => item < 10);
    },
    listCount () {
      return this.$store.getters.listCount;
    }
  }

}
</script>

这里我们可以发现,传入的第二次参数getters其实就是当前的getters中包含的所有的方法

actions的使用

前言:mutation里不应该异步操作数据,所以有了actions选项。action与mutation很像,不同的是action里面提交的是mutation,并且可以异步操作业务逻辑。action在组件内通过$store.dispatch触发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//在store.js中
export default new Vuex.Store({
  state: {
    count: 0,
    list: [1, 5, 8, 10, 30, 50]
  },
  actions: {
    increment(context) {
      context.commit('increment');
    }
  }
})

//data.vue中
  methods: {
    //监听数据的呀
    changes () {
      console.log(1);
    },
    handleIncrement () {
      this.$store.dispatch('increment');
    }
  }

感觉有点多次一举,因为可以直接通过mutation加以实现的呀,没必要通过action中转一次,但是加了异步就不一样了,我们用定时器在一秒后提交mutation,示例代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//store.js中的action中
    asyncIncrement(context, callback) {
      setTimeout(() => {
        context.commit('increment');
        callback()
      }, 1000)
    }

//data.vue中
  methods: {
     //handleAsyncIncrement   这个名字为点击事件名称,放置在+1的按钮上
    handleAsyncIncrement () {
      this.$store.dispatch('asyncIncrement', () => {
        console.log(this.$store.state.count)
      })
    }
  }

mutations、actions看起来很相似,可能会觉得不知道该用哪个,但是Vuex很像是一种与开发者的约定,所以涉及改变数据的,就是用mutations,存在业务逻辑的,就用actions,至于将业务逻辑放在action里还是Vue组件里完成,就需要更具实际场景拿捏了。

Vuex最后一个知识点:modules

前言:modules用来将store分隔到不同的模块,当你的项目足够大的时候,store里面的state、getters、actions会非常多,都放在一个store.js中显得不太友好,所以写入到不同的文件中,每个module拥有自己的state、getters、actions、mutations,二期可以多层嵌套

作者: huanggr

为您推荐

7

发表评论

电子邮件地址不会被公开。 必填项已用*标注

评论列表 1人参与

  1. 曾经有一个面试者我问我一个问题,ajax请求方法你把它封装在vue哪里?
    我说我有两个封装位置。
    第一个是封装在全局混入中。
    第二个是封装在vuex的util模块中。
    你是如何封装的呢?