一. 需求/技術分析
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 : 原創博客請在轉載時保留原文鏈接或在文章開頭加上本人博客地址,否則保留追究法律責任的權利。