文章目录
- 项目创建
- 初始渲染页面
- 对文本框进行双向数据绑定。在index.js定义一个inputValue来存储文本框的值,映射到组件app
- 接下来在文本框输入内容同步到state里面去
- 接下来,我们要去实现点击添加事件的操作
- 向文本框添加内容
- 完成删除项
- 复选框状态的绑定
- 修改任务事项完成的状态
- 剩余条数
- 清除已经完成的任务
- 动态切换按钮的高亮效果
- 实现动态切换
项目创建
创建的时候记得勾上vuex
1
2vue 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
19import 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
14import 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
5state: { 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
19methods: { // 文本框监听事件的方法,打印一下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
12addText () { // 判断文本框内容是否为空,为空返回提示信息 // 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
27mutations: { 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
7methods: { //通过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
27methods: { // 文本框监听事件的方法,打印一下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
36mutations: { 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
11cbStatusChanged (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
37methods: { // 文本框监听事件的方法,打印一下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
41mutations: { 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
7getters: { // 统计没有完成的任务的条数 unDoneLength (state) { return state.list.filter(x => x.done === false).length } }
把过滤的内容映射到app里
1
2import { mapState, mapGetters } from 'vuex'
1
2
3
4
5
6
7computed: { //列表内容和文本框内容的映射 ...mapState(['list', 'inputValue']), //剩余条数的映射 ...mapGetters(['unDoneLength'])
1
2<span>{{unDoneLength}}条剩余</span>
清除已经完成的任务
先要在清除已完成的a标签设置点击事件
,定义方法clearFinshItem
,commit
触发mutations里面的方法clearFinshItemDone
1
2
3
4clearFinshItem () { 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
5showItemList (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
10state: { // 渲染列表 list: [], // 文本框的内容 inputValue: 'qxtzmr', // id 在下面每添加一项自增1 next_id: 5, viewKey: 'all' }
1
2
3
4
5computed: { ...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
22getters: { // 统计没有完成的任务的条数 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
5computed: { ...mapState(['inputValue', 'viewKey']), ...mapGetters(['unDoneLength', 'infoList']) }
1
2<a-list bordered :dataSource="infoList" class="dt_list">
最后
以上就是务实哈密瓜最近收集整理的关于Vuex的todos案例的全部内容,更多相关Vuex内容请搜索靠谱客的其他文章。
发表评论 取消回复