一. 需求/技术分析
1. 需求分析
(1).实现默认数据的加载,可以分类显示全部、未完成、已完成的数据。
(2).可以添加新数据、删除列表数据。
(3).点击可以选中 和 取消选中,实时显示多少条未选中。
(4).清除已完成
2. 技术分析
使用Vuex对数据统一管理,state维护数据,mutations声明方法,actions声明异步方法(axios获取数据),getters对数据进行再处理。
二. 案例实现
1. 创建含有Vuex的项目
创建步骤可参考图形化界面的创建模式:https://www.cnblogs.com/yaopengfei/p/14506321.html
创建的过程中需要选中Vuex这一项:
2. 导入三方包
(1). 安装 ant-design-vue,【npm i ant-design-vue -S】, 然后在main.js中进行引入
// 1. 导入 ant-design-vue 组件库 import Antd from 'ant-design-vue' // 2. 导入组件库的样式表 import 'ant-design-vue/dist/antd.css' // 3. 安装组件库 Vue.use(Antd)
(2). 安装axios,【npm i axios -S】,然后在vuex对应的index.js页面中进行引入
// 引入axios import axios from 'axios'
3. 修改部分配置
(1). 配置端口,新建vue.config.js文件
module.exports = { devServer: { port: 8087, open: true } }
(2). 忽略ESLint校验,新增 .eslintignore文件
*.vue
*.js
4. Vuex核心代码
index.js
import Vue from 'vue' import Vuex from 'vuex' // 引入axios import axios from 'axios' Vue.use(Vuex) export default new Vuex.Store({ state: { //所有任务列表 list: [], //文本输入框中的值 inputValue: 'xxx', nextId: 5, viewKey: 'all' }, mutations: { // 1.初始化数据 initList(state, myData) { state.list = myData }, // 2.赋值文本框数据 setInputValue(state, myData) { state.inputValue = myData }, // 3.添加列表项 addItem(state) { const obj = { id: state.nextId, info: state.inputValue.trim(), done: false } state.list.push(obj); state.nextId++; state.inputValue = ''; }, // 4. 删除列表项(根据id) removeItem(state, id) { // 根据id查找索引 const i = state.list.findIndex(x => x.id === id); if (i != -1) { state.list.splice(i, 1); } }, // 5. 修改列表项状态 changeStatus(state, param) { const i = state.list.findIndex(x => x.id === param.id); if (i !== -1) { state.list[i].done = param.status; } }, // 6. 清除已经完成任务 cleanFinsh(state) { state.list = state.list.filter(x => x.done === false); }, //7. 修改视图关键字 changeViewKey(state, key) { state.viewKey = key; } }, actions: { getList(context) { // data这里解构赋值 axios.get('/list.json').then(({ data }) => { console.log(data); context.commit('initList', data); }) } }, getters: { // 1.统计未完成任务的个数 unDoneLength(state) { return state.list.filter(x => x.done === false).length; }, // 2.处理数据分类 infolist(state) { if (state.viewKey === 'all') { return state.list } if (state.viewKey === 'undone') { return state.list.filter(x => !x.done) } if (state.viewKey === 'done') { return state.list.filter(x => x.done) } return state.list } } })
main.js
import Vue from 'vue' import App from './App.vue' import store from './store' // 1. 导入 ant-design-vue 组件库 import Antd from 'ant-design-vue' // 2. 导入组件库的样式表 import 'ant-design-vue/dist/antd.css' // 3. 安装组件库 Vue.use(Antd) Vue.config.productionTip = false new Vue({ store, render: h => h(App) }).$mount('#app')
5. App.vue页面核心代码
<template> <div id="app"> <a-input placeholder="请输入任务" class="my_ipt" :value="inputValue" @change="handleInputChange" /> <a-button type="primary" @click="addItemToList">添加事项</a-button> <a-list bordered :dataSource="infolist" class="dt_list"> <a-list-item slot="renderItem" slot-scope="item"> <!-- 复选框 --> <a-checkbox :checked="item.done" @change="(e) => {cbStatusChanged(e, item.id)}">{{item.info}}</a-checkbox> <!-- 删除链接 --> <a slot="actions" @click="removeItemById(item.id)">删除</a> </a-list-item> <!-- footer区域 --> <div slot="footer" class="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="cleanFinsh">清除已完成</a> </div> </a-list> </div> </template> <script> import { mapState, mapGetters } from 'vuex' export default { name: 'app', data() { return {} }, created() { this.$store.dispatch('getList') }, computed:{ ...mapState(['list', 'inputValue', 'viewKey']), ...mapGetters(['unDoneLength', 'infolist']) }, methods: { // 1. 监听文本框内容变化 handleInputChange(e) { // console.log(e.target.value) this.$store.commit('setInputValue', e.target.value) }, // 2. 向列表中添加数据 addItemToList() { if (this.inputValue.trim().length <= 0) { return this.$message.warning('内容不能为空'); } this.$store.commit('addItem'); }, // 3.删除列表数据 removeItemById(id) { this.$store.commit('removeItem', id); }, // 4.监听复选框状态变化事件 cbStatusChanged(e, id) { const param = { id: id, status: e.target.checked } this.$store.commit('changeStatus', param) }, // 5.修改页面上的展示数据 changeList(key) { this.$store.commit('changeViewKey', key) }, // 6.清除已完成的任务 cleanFinsh() { this.$store.commit('cleanFinsh'); } }, } </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>
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 声 明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。