我是靠谱客的博主 务实哈密瓜,这篇文章主要介绍Vuex的todos案例,现在分享给大家,希望可以做个参考。

文章目录

      • 项目创建
      • 初始渲染页面
      • 对文本框进行双向数据绑定。在index.js定义一个inputValue来存储文本框的值,映射到组件app
      • 接下来在文本框输入内容同步到state里面去
      • 接下来,我们要去实现点击添加事件的操作
      • 向文本框添加内容
      • 完成删除项
      • 复选框状态的绑定
      • 修改任务事项完成的状态
      • 剩余条数
      • 清除已经完成的任务
      • 动态切换按钮的高亮效果
      • 实现动态切换

项目创建

创建的时候记得勾上vuex

复制代码
1
2
vue create vuex-todos

配置App根组件

复制代码
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
62
63
64
<template> <div id="app"> <a-input placeholder="请输入任务" class="my_ipt" /> <a-button type="primary">添加事项</a-button> <a-list bordered :dataSource="list" class="dt_list"> <a-list-item slot="renderItem" slot-scope="item"> <!-- 复选框 --> <a-checkbox>{{ item.info }}</a-checkbox> <!-- 删除链接 --> <a slot="actions">删除</a> </a-list-item> <!-- footer区域 --> <div slot="footer" class="footer"> <!-- 未完成的任务个数 --> <span>0条剩余</span> <!-- 操作按钮 --> <a-button-group> <a-button type="primary">全部</a-button> <a-button>未完成</a-button> <a-button>已完成</a-button> </a-button-group> <!-- 把已经完成的任务清空 --> <a>清除已完成</a> </div> </a-list> </div> </template> <script> export default { name: 'app', data () { return { } }, } </script> <style scoped> #app { padding: 10px; } .my_ipt { width: 500px; margin-right: 10px; } .dt_list { width: 500px; margin-top: 10px; } .footer { display: flex; justify-content: space-between; align-items: center; } </style>

配置main.js

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import Vue from 'vue' import App from './App.vue' // 1. 导入 ant-design-vue 组件库 import Antd from 'ant-design-vue' // 2. 导入组件库的样式表 import 'ant-design-vue/dist/antd.css' import store from '@/store/index.js' Vue.config.productionTip = false // 3. 安装组件库 Vue.use(Antd) new Vue({ render: h => h(App), store }).$mount('#app')

配置store的index.js

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import Vue from 'vue' import Vuex from 'vuex' import axios from 'axios' Vue.use(Vuex) export default new Vuex.Store({ state: { }, mutations: { }, actions: { }, modules: { }, })

在public下面新建一个list .json 渲染页面用的

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[ { "id": 0, "info": "Racing car sprays burning fuel into crowd.", "done": true }, { "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 battles huge wildfires.", "done": false } ]

初始渲染页面

app根组件定义了一个created,只要页面加载就会执行created,就只直接通过dispatch调用这个异步函数getList

复制代码
1
2
3
4
5
//去调用actions里面的getList方法,浏览器只要加载页面就会触发created created () { this.$store.dispatch('getList') }

通过axios异步获取list.json的数据内容,然后用commit去访问mutations里面的initList方法,并且返回数据data给initList的第二个参数list,initList的第一个参数一定是state,mutations的list赋值给state.list,最后state得到了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
//index.js import Vue from 'vue' import Vuex from 'vuex' import axios from 'axios' Vue.use(Vuex) export default new Vuex.Store({ state: { list: [] }, mutations: { initList (state, list) { state.list = list } }, actions: { // app根组件定义了一个created,只要页面加载就会执行created,就只直接通过dispatch调用这个异步函数getList // 通过axios异步获取list.json的数据内容,然后用commit去访问mutations里面的initList方法,并且返回数据data给initList的第二个参数list,initList的第一个参数一定是state,mutations的list赋值给state.list,最后state得到了list的数据 // 通过mapState把state的list映射到app根组件(先要导入mapState) getList (context) { axios.get('/list.json').then(({ data }) => { console.log(data) context.commit('initList', data) }) } }, modules: { } })

通过mapState把state的list映射到app根组件(先要导入mapState),App根组件得到了list,可以渲染页面

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script> import { mapState } from 'vuex' export default { name: 'app', data () { return { } }, created () { this.$store.dispatch('getList') }, computed: { ...mapState(['list']) } } </script>

在这里插入图片描述

在这里插入图片描述

对文本框进行双向数据绑定。在index.js定义一个inputValue来存储文本框的值,映射到组件app

复制代码
1
2
3
4
5
state: { list: [], inputValue: 'aaaa' }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script> import { mapState } from 'vuex' export default { name: 'app', data () { return { } }, //页面加载访问created,调用acyions异步函数 created () { this.$store.dispatch('getList') }, computed: { ...mapState(['list', 'inputValue']) } } </script>

找到文本框,进行绑定 :value="inputValue"

复制代码
1
2
<a-input placeholder="请输入任务" class="my_ipt" :value="inputValue"/>

在这里插入图片描述

接下来在文本框输入内容同步到state里面去

在文本框设置一个监听事件,只要文本框内容发生变化就会监听到打印一下监听内容
定义一个文本框监听事件

复制代码
1
2
<a-input placeholder="请输入任务" class="my_ipt" :value="inputValue" @change="handelInputChange"/>

文本框监听事件的方法,打印一下e,和文本框变化的内容

复制代码
1
2
3
4
5
6
7
8
9
//app.vue methods: { //文本框监听事件的方法,打印一下e,和文本框变化的内容 handelInputChange (e) { console.log('eeeeee', e) console.log(e.target.value) } }

在这里插入图片描述
得到了这个文本框变化的值,我们需要把这个值同步的和state里面的值一起变化

app组件的监听文本框变化用commit来触发mutations参数一是mutations里面定义的方法,参数二是需要给val传过来的值,val得到的值再传给state里面的inputValue

复制代码
1
2
3
4
5
6
7
8
9
10
11
//app.vue methods: { // 文本框监听事件的方法,打印一下e,和文本框变化的内容 handelInputChange (e) { console.log('eeeeee', e) console.log(e.target.value) //app组件的监听文本框变化用commit来触发mutations,参数一是mutations里面定义的方法,参数二是需要给val传过来的值 //这个方法可以调用mutations,还可以传递参数 this.$store.commit('setInputValue', e.target.value) }
复制代码
1
2
3
4
5
6
7
8
//index.js //app组件的监听文本框变化用commit来触发mutations,参数一是mutations里面定义的方法,参数二是需要给val传过来的值,val得到的值再传给state里面的inputValue //setInputValue里面的参数2把值传给state里面的inputValue setInputValue (state, val) { state.inputValue = val } }

在这里插入图片描述

接下来,我们要去实现点击添加事件的操作

添加添加事项点击事件,在methods里面定义方法触发

复制代码
1
2
<a-button type="primary" @click="addText" >添加事项</a-button>

判断文本框内容是否为空,为空返回提示信息
inputValue是文本框的内容,已经从state映射到computed
trim去除两端空格
$message.warning可以返回为空的打印信息 主要是导入了这个css组件库import 'ant-design-vue/dist/antd.css'

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
methods: { // 文本框监听事件的方法,打印一下e,和文本框变化的内容 handelInputChange (e) { console.log('eeeeee', e) console.log(e.target.value) // app组件的监听文本框变化用commit来触发mutations,参数一是mutations里面定义的方法,参数二是需要给val传过来的值 this.$store.commit('setInputValue', e.target.value) }, // 向列表中新增内容 addText () { // 判断文本框内容是否为空,为空返回提示信息 // inputValue是文本框的内容,已经从state映射到computed // trim去除两端空格 if (this.inputValue.trim().length <= 0) { return this.$message.warning('文本框内容不能为空') } } }

请添加图片描述

向文本框添加内容

只要用户点击了添加按钮就会通过$store.commit触发mutations里面的addItem方法

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
addText () { // 判断文本框内容是否为空,为空返回提示信息 // inputValue是文本框的内容,已经从state映射到computed // trim去除两端空格 if (this.inputValue.trim().length <= 0) { return this.$message.warning('文本框内容不能为空') } //只要用户点击了添加按钮就会通过$store.commit触发mutations里面的addItem方法 this.$store.commit('addItem') }

addText触发了mutations的addItem,每点击一次就会向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
mutations: { initList (state, list) { state.list = list }, // app组件的监听文本框变化用commit来触发mutations,参数一是mutations里面定义的方法,参数二是需要给val传过来的值,val得到的值再传给state里面的inputValue // setInputValue里面的参数2把值传给state里面的inputValue setInputValue (state, val) { state.inputValue = val }, addItem (state) { //定义一个对象,最后添加到列表,里面要有id,info(文本框内容inputValue),done(在这里默认是fales) const listObj = { id: state.next_id, info: state.inputValue.trim(), done: false } //添加到list里面去 state.list.push(listObj) //每添加一个对象到list id++ state.next_id++ //每添加一个对象到list 文本框内容置为空 state.inputValue = '' } }

请添加图片描述

完成删除项

我们通过item传过来的id来指定删除那一项,在删除定义一个点击事件

复制代码
1
2
<a slot="actions" @click="removeItemId(item.id)">删除</a>

在methods定义方法,打印点击后那一项的id

复制代码
1
2
3
4
5
6
7
methods: { //通过item传过来的id来指定删除那一项 removeItemId (id) { console.log(id) } }

请添加图片描述
用这个方法去触发mutations里面的删除方法,并且传过去要删除项的id进行对比是否雨state里面的id相对应,如果相同就赋值给一个变量,我把它称为变量id,接着判断是否存在这个变量id,如果存在,删除当前变量id项

复制代码
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
methods: { // 文本框监听事件的方法,打印一下e,和文本框变化的内容 handelInputChange (e) { console.log('eeeeee', e) console.log(e.target.value) // app组件的监听文本框变化用commit来触发mutations,参数一是mutations里面定义的方法,参数二是需要给val传过来的值 this.$store.commit('setInputValue', e.target.value) }, // 向列表中新增内容 addText () { // 判断文本框内容是否为空,为空返回提示信息 // inputValue是文本框的内容,已经从state映射到computed // trim去除两端空格 if (this.inputValue.trim().length <= 0) { return this.$message.warning('文本框内容不能为空') } // 只要用户点击了添加按钮就会通过$store.commit触发mutations里面的addItem方法 this.$store.commit('addItem') }, // 通过item传过来的id来指定删除那一项 removeItemId (id) { this.$store.commit('removeItem', id) console.log(id) } }
复制代码
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
mutations: { initList (state, list) { state.list = list }, // app组件的监听文本框变化用commit来触发mutations,参数一是mutations里面定义的方法,参数二是需要给val传过来的值,val得到的值再传给state里面的inputValue // setInputValue里面的参数2把值传给state里面的inputValue setInputValue (state, val) { state.inputValue = val }, addItem (state) { // 定义一个对象,最后添加到列表,里面要有id,info(文本框内容inputValue),done(在这里默认是fales) const listObj = { id: state.next_id, info: state.inputValue.trim(), done: false } // 添加到list里面去 state.list.push(listObj) // 每添加一个对象到list id++ state.next_id++ // 每添加一个对象到list 文本框内容置为空 state.inputValue = '' }, // 根据id删除对应的任务事项 removeItem (state, id) { // findIndex去查询list里面的每一个id,如果会等于传过来的id那就通过变量接收 const idIndex = state.list.findIndex(x => x.id === id) // 如果存在idIndex的话,那就执行删除项,删除该id的删除项 if (idIndex !== -1) { state.list.splice(idIndex, 1) } } }

请添加图片描述

复选框状态的绑定

复制代码
1
2
<a-checkbox :checked="item.done">{{ item.info }}</a-checkbox>

在这里插入图片描述

修改任务事项完成的状态

监听复选框选中状态,只要点击了复选框按钮,就会触发cbStatusChanged方法,这个方法可以监听复选框状态发生的最新变化,把change接收到的事件对象e 传给cbStatusChanged

复制代码
1
2
<a-checkbox :checked="item.done" @change="(e)=>{cbStatusChanged(e)}">{{ item.info }}</a-checkbox>

在methods定义这个方法去监听复选框最新状态,这里我们打印出来是true还是false

复制代码
1
2
3
4
5
//通过e.target.checked可以接收到最新的选中状态 cbStatusChanged (e) { console.log(e.target.checked) }

接下里,我们需要知道我们点击复选框的id是哪一项,所以不仅仅要传事件对象e,还要传id

复制代码
1
2
<a-checkbox :checked="item.done" @change="(e)=>{cbStatusChanged(e,item.id)}">{{ item.info }}</a-checkbox>

打印出被改变选中id和被选中的状态

复制代码
1
2
3
4
5
// 通过e.target.checked可以接收到最新的选中状态 cbStatusChanged (e, id) { console.log(e.target.checked, id) }

通过这个方法可以cbStatusChanged触发commit触发mutations里面的changeStatus,定义一个对象,传给changeStatus的params,参数1是id,参数2是选中状态

复制代码
1
2
3
4
5
6
7
8
9
10
11
cbStatusChanged (e, id) { console.log(e.target.checked, id) //定义一个对象,传给changeStatus的params,参数1是id,参数2是选中状态 const param = { id: id, status: e.target.checked } this.$store.commit('changeStatus', param) } }
复制代码
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
methods: { // 文本框监听事件的方法,打印一下e,和文本框变化的内容 handelInputChange (e) { console.log('eeeeee', e) console.log(e.target.value) // app组件的监听文本框变化用commit来触发mutations,参数一是mutations里面定义的方法,参数二是需要给val传过来的值 this.$store.commit('setInputValue', e.target.value) }, // 向列表中新增内容 addText () { // 判断文本框内容是否为空,为空返回提示信息 // inputValue是文本框的内容,已经从state映射到computed // trim去除两端空格 if (this.inputValue.trim().length <= 0) { return this.$message.warning('文本框内容不能为空') } // 只要用户点击了添加按钮就会通过$store.commit触发mutations里面的addItem方法 this.$store.commit('addItem') }, // 通过item传过来的id来指定删除那一项 removeItemId (id) { this.$store.commit('removeItem', id) console.log(id) }, // 通过e.target.checked可以接收到最新的选中状态 cbStatusChanged (e, id) { console.log(e.target.checked, id) // 定义一个对象,传给changeStatus的params,参数1是id,参数2是选中状态 const param = { id: id, status: e.target.checked } this.$store.commit('changeStatus', param) } }

修改列表的选中状态

复制代码
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
mutations: { initList (state, list) { state.list = list }, // app组件的监听文本框变化用commit来触发mutations,参数一是mutations里面定义的方法,参数二是需要给val传过来的值,val得到的值再传给state里面的inputValue // setInputValue里面的参数2把值传给state里面的inputValue setInputValue (state, val) { state.inputValue = val }, addItem (state) { // 定义一个对象,最后添加到列表,里面要有id,info(文本框内容inputValue),done(在这里默认是fales) const listObj = { id: state.next_id, info: state.inputValue.trim(), done: false } // 添加到list里面去 state.list.push(listObj) // 每添加一个对象到list id++ state.next_id++ // 每添加一个对象到list 文本框内容置为空 state.inputValue = '' }, // 根据id删除对应的任务事项 removeItem (state, id) { // findIndex去查询list里面的每一个id,如果会等于传过来的id那就通过变量接收 const idIndex = state.list.findIndex(x => x.id === id) // 如果存在idIndex的话,那就执行删除项,删除该id的删除项 if (idIndex !== -1) { state.list.splice(idIndex, 1) } }, // 修改列表的选中状态 changeStatus (state, param) { const idIndex = state.list.findIndex(x => x.id === param.id) state.list[idIndex].done = param.status } }

请添加图片描述

剩余条数

猪index.js定义一个getters,对每一项done进行过滤

复制代码
1
2
3
4
5
6
7
getters: { // 统计没有完成的任务的条数 unDoneLength (state) { return state.list.filter(x => x.done === false).length } }

把过滤的内容映射到app里

复制代码
1
2
import { mapState, mapGetters } from 'vuex'
复制代码
1
2
3
4
5
6
7
computed: { //列表内容和文本框内容的映射 ...mapState(['list', 'inputValue']), //剩余条数的映射 ...mapGetters(['unDoneLength'])
复制代码
1
2
<span>{{unDoneLength}}条剩余</span>

请添加图片描述

清除已经完成的任务

先要在清除已完成的a标签设置点击事件,定义方法clearFinshItem,commit触发mutations里面的方法clearFinshItemDone

复制代码
1
2
3
4
clearFinshItem () { this.$store.commit('clearFinshItemDone') }

通过过滤,把没有选中为false的过滤出来,重新赋值给state.list

复制代码
1
2
3
4
5
// 清除已经完成的任务 clearFinshItemDone (state) { state.list = state.list.filter(x => x.done === false) }

请添加图片描述

动态切换按钮的高亮效果

复制代码
1
2
3
4
5
showItemList (key) { console.log(key) this.$store.commit('showList', key) }
复制代码
1
2
3
4
5
// 修改试图关键字,参数2:外界传进来的key showList (state, key) { state.viewKey = key }
复制代码
1
2
3
4
5
6
7
8
9
10
state: { // 渲染列表 list: [], // 文本框的内容 inputValue: 'qxtzmr', // id 在下面每添加一项自增1 next_id: 5, viewKey: 'all' }
复制代码
1
2
3
4
5
computed: { ...mapState(['list', 'inputValue', 'viewKey']), ...mapGetters(['unDoneLength']) }
复制代码
1
2
3
4
5
6
<a-button-group> <a-button :type="viewKey==='all'? 'primary' :'default' " @click="showItemList('all')">全部</a-button> <a-button :type="viewKey==='unfinsh'?'primary':'default'" @click="showItemList('unfinsh')">未完成</a-button> <a-button :type="viewKey==='finsh'?'primary':'default'" @click="showItemList('finsh')">已完成</a-button> </a-button-group>

请添加图片描述

实现动态切换

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
getters: { // 统计没有完成的任务的条数 unDoneLength (state) { return state.list.filter(x => x.done === false).length }, infoList (state) { if (state.viewKey === 'all') { return state.list } //! x.done 就是 false if (state.viewKey === 'unfinsh') { return state.list.filter(x => !x.done) } if (state.viewKey === 'finsh') { return state.list.filter(x => x.done) } // 如果三者都不是 直接返回全部 return state.list } }
复制代码
1
2
3
4
5
computed: { ...mapState(['inputValue', 'viewKey']), ...mapGetters(['unDoneLength', 'infoList']) }
复制代码
1
2
<a-list bordered :dataSource="infoList" class="dt_list">

请添加图片描述

最后

以上就是务实哈密瓜最近收集整理的关于Vuex的todos案例的全部内容,更多相关Vuex内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(66)

评论列表共有 0 条评论

立即
投稿
返回
顶部