最近学习了一下Vuex,在这里简单的做一个笔记。由于本人技术欠缺,有问题的地方欢迎指正。
什么是Vuex?
引用官网的话:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
注:个人觉得比较适用于项目中数据有关联性并且运用相同组件的情况,例如,购物车,答题等等。本文使用的案例就是一个答题demo。
核心概念
- State: 数据源。
const store = new Vuex.Store({
state: {
count: 1
},
}
-
Getter: store 的计算属性
-
Mutation:Mutation里面装了更改state状态的事件。
-
Action:操作mutation里面的事件。
注:Mutation和Action的区别
1.mutation是同步的,Action 可以包含任意异步操作
2.Action 提交的是 mutation,而不是直接变更状态 -
Module:模块,为了解决当应用变得非常复杂时,store 对象就有可能变得相当臃肿的情况。
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
demo
demo需求:一个答题小测验。最重要的一点就是记录每道题的选择答案,提交答卷的时候根据答案进行打分。
首先,新建一个store文件,并且新建一个store.js文件
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
/**************************************************************************************
state存放数据源
**********************************************************************************/
state:{
itemNum:1,//第几题
answerid: [], //答案id
itemDetail: [{
"topic_id": 20,
"topic_name": "大熊猫是哪个国家的?"
"topic_answer": [{
"topic_answer_id": 1,
"topic_id": 20,
"answer_name": "中国",
"is_standard_answer": 1
},
{
"topic_answer_id": 2,
"topic_id": 21,
"answer_name": "加拿大",
"is_standard_answer": 0
},{
"topic_answer_id": 3,
"topic_id": 23,
"answer_name": "哥伦比亚",
"is_standard_answer": 0
}]
},
.........
]
},
/*********************************************************************************/
mutations存放数据逻辑
*********************************************************************************/
mutations:{
//记录答案
REMBER_ANSWER(state, id){
state.answerid.push(id)
},
//进入下一题
ADD_ITEMNUM(state,num){
state.itemNum += num
},
//初始化数据
INITIAL_DATA(state){
state.itemNum = 1;
state.allTime = 0;
state.answerid = [];
}
},
/********************************************************************************/
actions 操作mutations
********************************************************************************/
actions:{
addNum({commit, state},id) {
commit('REMBER_ANSWER',id)
if(state.itemNum < state.itemDetail.length){
commit('ADD_ITEMNUM',1)
}
},
initialzeDate({commit}){
commit('INITIAL_DATA')
//这里提交的是mutations中定义的INITIAL_DATA
}
}
})
export default store
然后,新建一个组件question.vue,答题页面
<template>
<!--循环渲染问题答案-->
<section>
<header >{{itemDetail[itemNum-1].topic_name}}</header>
<ul>
<li v-for="(item, index) in itemDetail[itemNum-1].topic_answer"
:key='index' @click="choosed(index, item.answer_id)">
{{item.answer_name}}
</li>
</ul>
</div>
<span @click="nextItem" v-if="itemNum < itemDetail.length">下一题</span>
<span v-else @click="submitAnswer">提交</span>
</section>
</template>
<script>
import { mapState, mapActions } from 'vuex'
export default {
name:'pageItem',
data(){
return {
itemId: null, //题目ID
choosedNum: null, //选中答案索引
choosedId:null //选中答案id
}
},
/********************************************************************************/
首先,在组件中使用在store中定义的状态数据,需要在组件的computed属性里声明这些变量
例如:
computed:{
itemNum(){
return this.$store.state.itemNum
}
}
由于state有多个数据,一个一个写就很麻烦,因此mapState因运而生,它可以帮你简单的引用这些变量,如下所示
/******************************************************************************/
computed: mapState([
'itemNum', //第几题
'itemDetail', //题目详情
]),
methods:{
/********************************************************************************/
在组件中,想要使用Action中定义的方法,也需要挂载,其辅助函数为mapActions。通过...对象扩展运算符,将返回值解析就成为methods的属性,如下所示,'addNum','initialzeDate'是store.js中actions定义的。通过mapActions,可以在组件中直接使用这些方法了
/******************************************************************************/
...mapActions([
'addNum','initialzeDate'
]),
nextItem(){
if(this.choosedNum != null){
this.choosedNum = null;
//保存答案,题目索引加一,进入下一题
this.addNum(this.choosedId)
}else {
alert('您还没有选择答案哦')
}
},
//提价答案
submitAnswer(){
if(this.choosedNum != null){
this.addNum(this.choosedId);
}
},
//选中问题
choosed(index,id){
this.choosedNum = index;
this.choosedId = id;
},
}
}
</script>
结语,这是初次尝试Vuex,文中的代码是仿照别人写的,具体来源不太清楚(若有侵权,请联系)。