文章目录
前言
本文将从Vuex的核心概念出发,通过讲解一个待办清单的小项目,帮助大家更好的理解Vuex。此文主要是根据近日学习的关于Vuex的内容,整理出的学习笔记,用来巩固与记录。欢迎大家交流与讨论!😊
主要参考视频为黑马程序员的“Vue全家桶-Vuex” 原视频地址
https://www.bilibili.com/video/BV1h7411N7bg?from=search&seid=5930582975536399924&spm_id_from=333.337.0.0
若有侵权,请邮箱联系1544945335@qq.com 联系,我会及时删除。敬礼!
一、Vuex是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 +
库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
参考教程:https://vuex.vuejs.org/zh/
那么什么是状态管理模式呢?在一般情况下,我们的vue应用在渲染数据时,是一个单项数据流的过程,驱动的数据源为状态,状态会以声明方式映射到视图,用户通过在视图上操作又会导致状态变化。如图所示:
我们多个视图依赖同一状态(数据)、或不同的视图需要变更同一状态(数据)时,若没有一个统一的状态管理器,但是又需要实现数据共享时,过程就会变得麻烦。按照传统方式,我们是可以通过各个组件传参来达成数据共享,但若项目变大,传参的过程就会变得相当繁琐,且后期维护的成本也很高。
所以Vuex作为一个状态管理器,可以把不同组件的共享状态抽离出来,集中管理便于后期维护,并利用vuex的响应式的特点从而实现高效进行状态更新。
Vuex核心概念
在安装好vuex之后,将出现store文件夹,里面有index.js的文件,代码如下:
import Vue from'vue'import Vuex from'vuex'
Vue.use(Vuex)exportdefaultnewVuex.Store({
state:{},
mutations:{},
actions:{},
modules:{}})
下面将一一介绍Store的核心。
1. State
State为Vuex的公共状态,提供唯一的数据源,用来存储公共的数据。
- 例如我们将要实现todoList的列表事项就可以作为公共数据放在state中。
代码如下:
state:{// 所有的任务列表
list:[],},
当我们要访问存放在State里面的数据可通过以下两种方式:
- 组件访问State中数据的第一种方式:
this.$stroe.state.全局数据名称
- 组件访问State中数据的第二种方式:
//1. 从vuex中按需导入 mapState 函数import{ mapState }from'vuex'``````//2. 通过 mapState 函数,将当前组件需要的全局数据映射为当前组件computed:{...mapState(['list']),},
2. Mutations
Mutations用于变更Store中的数据。
- 只能通过mutations变更Store数据,不可以直接操作Store中的数据。
假设要实现一个点击自增的功能,首先需要在Store中定义Mutations代码如下:
exportdefaultnewVuex.Store({
state:{
count:0},
mutations:{//加1add(state){//变更状态
state.count++}//携带参数,加naddN(state,n){//变更状态
state.count += n
}},})
触发mutations需通过以下两种方式:
- 触发mutations的第一种方式:
methods:{handle(){this.$store.commit('add')}}//携带参数methods:{handle1(){this.$store.commit('addN',n)}}
- 触发mutations的第二种方式:
//1. 从vuex中按需导入 mapMutations 函数import{ mapMutations }from'vuex'``````//2. 将指定的 mutations 函数,映射为当前组件的methods方法methods:{...mapMutations(['add']),handle(){this.add()},//携带参数handle1(){this.addN(5)}},
3.Actions
Actions用于处理异步任务
- 如果通过异步操作变更数据,必须通过Actions,而不能使用Mutations
- 在Actions中还是要通过触发Mutations方式变更数据
假设要实现一个延时添加的功能,在Store中定义actions代码如下:
exportdefaultnewVuex.Store({
state:{
count:0},
mutations:{add(state){//变更状态
state.count++}},
actions:{addAsync(context){//异步动作,如延时添加setTimeout(()=>{
context.commit('add')},1000)}},})
触发actions可通过以下两种方式:
- 触发actions的第一种方式:
methods:{handle(){this.$store.dispatch('addAsync')}}
- 触发actions的第二种方式:
//1. 从vuex中按需导入 mapActions 函数import{ mapAction }from'vuex'``````//2. 将指定的 mutations 函数,映射为当前组件的methods方法methods:{...mapActions(['addAsync']),},
4.Getters
Getters用于对Store中的数据进行加工处理形成新的数据。
- Getter可以对Store中的数据进行加工处理形成新的数据,类似Vue的计算属性
- Store中数据发生变化,Getters的数据也会发生变化
在Store中定义Getter代码如下:
exportdefaultnewVuex.Store({
state:{
count:0},
getters:{showNum(state){return'当前最新的数量是【'+ state.count +'】'},}},})
使用getters可通过以下两种方式:
- 使用getters的第一种方式:
this.$store.getters.名称
- 使用getters的第二种方式:
//1. 从vuex中按需导入 mapActions 函数import{ mapGetters }from'vuex'``````//2. 将指定的 mutations 函数,映射为当前组件的methods方法computed:{...mapGetters(['showNum']),},
(携带参数)
二、todoList待办清单
1.初始化项目-基于已有样式模版实现Todos基本布局
我们的待办清单基本布局与功能点如上图所示
html代码如下:
<template><divid="app"><a-inputplaceholder="请输入任务"class="my_ipt":value="inputValue"@change="handleInputChange"/><a-buttontype="primary"@click="addItemToList">添加事项</a-button><!-- vuex中store的list为数据源 --><a-listbordered:dataSource="list"class="dt_list"><a-list-itemslot="renderItem"slot-scope="item"><!-- 复选框 --><a-checkbox:checked="item.done"@change="cbStatusChanged($event, item.id)">{{ item.info }}</a-checkbox><!-- 删除链接 --><aslot="actions"@click="removeItemById(item.id)">删除</a></a-list-item><!-- footer区域 --><divclass="footer"slot="footer"><span>{{ unDoneLength }}条剩余</span><a-button-group><a-button:type="viewKey === 'all' ? 'primary' : 'default'"@click="changeList('all')">全部</a-button><a-button:type="viewKey === 'undone' ? 'primary' : 'default'"@click="changeList('undone')">未完成</a-button><a-button:type="viewKey === 'done' ? 'primary' : 'default'"@click="changeList('done')">已完成</a-button></a-button-group><a@click="clean">清除已完成</a></div></a-list></div></template>
下面将按功能点分别介绍实现思路
2.使用axios获取数据
前端模拟数据可把list列表数据单独存放在一个json文件里,利用axios获取
字段释义:
id
待办清单项idinfo
待办清单项内容done
是否已完成(true
为已完成,false
为未完成)
list.json 代码如下:
[{"id":0,"info":"Racing car sprays burning fuel into crowd.","done":false},{"id":1,"info":"Japanese princess to wed commoner.","done":false},{"id":2,"info":"Australian walks 100km after outback crash.","done":true},{"id":3,"info":"Man charged over missing wedding girl.","done":false},{"id":4,"info":"Los Angeles bat∏tles huge wildfires.","done":false}]
在store/index.js 中,首先在state中定义数据
state:{// 所有的任务列表
list:[],},
在页面初始化时获取数据
created(){// 1、App.vue 页面初始化时调用vuex中的action 异步获取数据this.$store.dispatch('getList')},
Actions异步获取本地数据
actions:{// 2、在action中 异步获取数据,并把数据提交给mutations中initList函数处理梳理getList(context){
axios.get('/list.json').then(({ data })=>{
console.log(data)
context.commit('initList', data)})},addAsync(context){// 异步动作,如延时添加setTimeout(()=>{
context.commit('add')},1000)}},
Actions在mutation中对state数据进行赋值
mutations:{// 3、在mutation中对state数据进行赋值initList(state, list){
state.list = list
},
App.vue 中Actions在mutation中对state数据进行赋值
// 4、使用store的计算属性,把store中存储的数据映射过来
computed:{...mapState(['list']),},
3.添加列表事项
实现思路:
- 首先监听输入框内容,实时传给vuex
- vuex中mutations设置函数,实时获取到文本框输入的内容
- 点击添加,传给对应的mutations中的添加函数
- 在vuex的mutations的添加函数中,把列表项(一个对象)添加到state存储的数据中
App.vue 代码如下:
methods:{// 监听文本handleInputChange(e){
console.log(e.target.value)this.$store.commit('setInputValue', e.target.value)},// 向列表中增加Item项addItemToList(){if(this.inputValue.trim().length <=0){returnthis.$message.warning('输入内容不能为空')}else{this.$store.commit('addItem')}},
store/index.js 代码如下:
state:{// 所有的任务列表
list:[],// 文本框内容
inputValue:'',//id
nextId:5,},
mutations:{// 为store中的inputValue赋值setInputValue(state, val){
state.inputValue = val
},addItem(state){const obj ={
id: state.nextId,
info: state.inputValue.trim(),
done:false}
state.list.push(obj)
state.nextId++
state.inputValue =''},},
4.删除列表事项
实现思路:
- 首先获取到删除的id
- 点击删除,把对应的id传给对应的mutations中的删除函数
- 在vuex的mutations的删除函数中,筛选出对应id的对象,进行删除
App.vue 代码如下:
methods:{// 根据id进行删除removeItemById(id){this.$store.commit('removeItem', id)},},
store/index.js 代码如下:
mutations:{removeItem(state, id){const i = state.list.findIndex((x)=> x.id === id)if(i !==-1){
state.list.splice(i,1)}},},
5.选中标记已完成
实现思路:
- 利用组件的
change
属性,当列表选项选中状态改变时获取id以及当前选中状态 - 传给对应的mutations函数
- 在vuex的mutations的改变选中状态函数中,根据id找到列表项并更改选中状态
App.vue 代码如下:
cbStatusChanged(e, id){const param ={
id: id,
status: e.target.checked
}this.$store.commit('changeStatus', param)},
store/index.js 代码如下:
mutations:{changeStatus(state, param){const i = state.list.findIndex((x)=> x.id === param.id)
state.list[i].done = param.status
},},
6.显示待完成条数
实现思路:
- 对已有list列表进行筛选
- 筛选出状态等于false的列表项
store/index.js 代码如下:
getters:{unDoneLength(state){return state.list.filter((x)=> x.done ===false).length
},},
7.切换tabs显示不同内容
实现思路:
- 切换tabs时首先tabs对应按钮的选中状态会改变,另外列表内容也会改变
- 给所有tabs(3个btn)绑定事件,当按钮点击时获取到当前选中的按钮内容,传给vuex
- vuex中state记录当前选中的按钮内容(全部、已完成、未完成)
viewKey
- 根据
viewKey
的变化,同步更改所有按钮type值,并设置组件选中样式(当然也有更方便的组件,不需要我们自己写) - 根据
viewKey
的变化,更新列表的数据源,这里用Getters处理
App.vue 代码如下:
changeList(key){this.$store.commit('changeList', key)}
store/index.js 代码如下:
mutations:{changeList(state, key){
state.viewKey = key
}},
html代码如下:
<a-button-group><a-button:type="viewKey === 'all' ? 'primary' : 'default'"@click="changeList('all')">全部</a-button><a-button:type="viewKey === 'undone' ? 'primary' : 'default'"@click="changeList('undone')">未完成</a-button><a-button:type="viewKey === 'done' ? 'primary' : 'default'"@click="changeList('done')">已完成</a-button></a-button-group>
store/index.js 代码如下:
getters:{infoList(state){if(state.viewKey ==='all'){return state.list
}if(state.viewKey ==='undone'){return state.list.filter((x)=> x.done ===false)}if(state.viewKey ==='done'){return state.list.filter((x)=> x.done ===true)}return state.list
}},
8.清除已完成
实现思路:
- 点击删除,删选出未完成的列表项
App.vue 代码如下:
methods:{clean(){this.$store.commit('clean')},},
store/index.js 代码如下:
mutations:{clean(state){
state.list = state.list.filter((x)=> x.done ===false)},},
总结
以上就是关于vuex的入门内容,本文仅仅简单介绍了vuex一些核心概念以及一个todoList待办清单的小例子!欢迎点赞评论收藏,一起学习一起进步!
版权归原作者 WH小可爱 所有, 如有侵权,请联系我们删除。