vue3+vant4+vuex4实现todolist备忘录案例

案例用的是vant-ui库,你可换成你自己用的ui库即可。
 
功能需求分析:
  1. 添加事项
  2. 删除事项
  3. 已完成删除
  4. 筛选:已完成、未完成
  5. 统计:剩余事项个数
安装vuex依赖包
npm install vuex --save

案例图片如下:

 

 1     <van-cell-group>
 2       <van-cell>
 3         <van-row>
 4           <van-col span="20">
 5             <van-field
 6               :value="content"
 7               @change="handleChange"
 8               placeholder="请输入内容"
 9             />
10           </van-col>
11           <van-col span="4">
12             <van-button type="primary" @click="onClickAdd" size="small"
13               >添加</van-button
14             >
15           </van-col>
16         </van-row>
17       </van-cell>
18       <van-cell v-for="(item, index) in listItem" :key="index">
19         <van-row class="bg flex">
20           <van-col span="2">
21             <van-checkbox
22               v-model="item.checked"
23               shape="square"
24               @change="onChange(item, index, $event)"
25             >
26             </van-checkbox>
27           </van-col>
28           <van-col span="16">
29             <div v-if="!item.checked" class="name">{{ item.name }}</div>
30             <van-field v-else v-model="item.name" placeholder="请输入内容" />
31           </van-col>
32           <van-col span="4">
33             <span @click="onClickDelete(item, index)" class="fontColor"
34               >删除</span
35             >
36           </van-col>
37         </van-row>
38       </van-cell>
39       <van-empty
40         v-if="listItem.length == 0"
41         image="https://fastly.jsdelivr.net/npm/@vant/assets/custom-empty-image.png"
42         image-size="40"
43         description="暂无数据"
44       />
45 
46       <div class="footer flex" v-if="items.length != 0">
47         <span>剩余{{ notFinsh }}项</span>
48         <van-tabs
49           v-model:active="active"
50           @click-tab="onClickTab"
51           shrink
52           type="card"
53           size="small"
54         >
55           <van-tab title="全部"></van-tab>
56           <van-tab title="未完成"></van-tab>
57           <van-tab title="已完成"></van-tab>
58         </van-tabs>
59         <span type="primary" @click="onClickClear" class="fontColor"
60           >删除已完成</span
61         >
62       </div>
63     </van-cell-group>

js和css代码如下:

 1 <script>
 2 import { useStore, mapState, mapGetters } from 'vuex'
 3 import { showToast } from 'vant'
 4 import { showConfirmDialog } from 'vant'
 5 import { ref, computed } from 'vue'
 6 export default {
 7   setup() {
 8     const store = useStore()
 9     const active = ref('1')
10     const content = computed(() => store.state.content)
11     const items = computed(() => store.state.items)
12     function onClickAdd() {
13       if (content.value == '') {
14         showToast('输入内容不能为空')
15       } else {
16         store.commit('addItem')
17       }
18     }
19     function handleChange(e) {
20       store.commit('setInputValue', e.target.value)
21     }
22     function onClickDelete(item, i) {
23       showConfirmDialog({
24         title: '提示',
25         message: '您确定要' + item.name + '删除吗?',
26       })
27         .then(() => {
28           store.commit('deleteItem', i)
29         })
30         .catch(() => {})
31     }
32     function onChange(item, index, e) {
33       item.checked != item.checked
34     }
35     function onClickClear() {
36       store.commit('clearItem')
37     }
38     function onClickTab(val) {
39       store.commit('changeItem', val.name)
40     }
41     return {
42       active,
43       onClickAdd,
44       onClickTab,
45       onClickClear,
46       onChange,
47       onClickDelete,
48       handleChange,
49       content,
50       items,
51     }
52   },
53   computed: {
54     ...mapGetters(['notFinsh', 'listItem']),
55   },
56 }
57 </script>
58 <style scoped>
59 .bg {
60   background: #fff;
61   width: 100%;
62 }
63 .fontColor {
64   color: #3071f1;
65   font-size: 12px;
66 }
67 .flex {
68   display: flex;
69   justify-content: space-between;
70   align-items: center;
71 }
72 .name {
73   text-align: left;
74   padding: 14px;
75 }
76 .bg >>> .van-field__control:focus {
77   outline: none;
78   border-color: #409eff;
79 }
80 .footer {
81   padding: 20px;
82 }
83 </style>

main.js引用vuex,并挂载到vue

import store from './store';
app.use(router).use(store);

 

 sotore.js代码如下:

 1 import { createStore } from 'vuex'
 2 
 3 export default createStore({
 4     state:{
 5         content:'',
 6         active:"",
 7         items:[{
 8             "name": "1111",
 9             "id": "1",
10             "checked": false
11         },{
12             "name": "222",
13             "id": "2",
14             "checked": true
15         },{
16             "name": "333",
17             "id": "3",
18             "checked": false
19         }],
20         id:0,
21     },
22     mutations:{
23         onChangeChecked(state,index,val){
24             state.items[index].name = val
25         },
26         todoUpdata(state,index,val){
27             state.items[index].name = val
28         },
29         setInputValue(state,val){
30             state.content = val
31         },
32        addItem(state){
33         var obj = {
34             "name": state.content,
35             "id": state.id,
36             "checked": false
37         }
38         console.log("obj",obj)
39         state.items.unshift(obj)
40         state.id ++
41         state.content = ""
42        },
43        deleteItem(state,i){
44         state.items.splice(i,1)
45        },
46        clearItem(state){
47         state.items = state.items.filter(x=>x.checked===false)
48        },
49        changeItem(state,val){
50             state.active = val
51        }
52     },
53     actions:{
54        
55     },
56     getters:{
57        notFinsh(state){
58         return state.items.filter(x=>x.checked===false).length
59        },
60        listItem(state){
61             //0全部 1未完成  2已完成
62             if(state.active==0){
63                 return state.items
64             }
65             if(state.active==1){
66                 return state.items.filter(x=>!x.checked)
67             }
68             if(state.active==2){
69                 return state.items.filter(x=>x.checked)
70             }
71             return state.items
72        }
73     }
74 }) 

            

                   QQ群:659182980                                               微信群 :扫一扫即可添加入群

         欢迎扫码加群,一起讨论,共同学习成长!

posted @ 2023-06-05 20:15  此夏_唯美  阅读(181)  评论(0编辑  收藏  举报