pinia实现todos

store/todos.js

javascript 复制代码
//导入defineStore
import {defineStore} from 'pinia'
const userTodosStore=defineStore('todos',{
state:()=>({
    // list:[
    //     {id:1,name:'吃饭',done:false},
    //     {id:2,name:'睡觉',done:true},
    //     {id:3,name:'打豆豆',done:false}
    // ],
    list:JSON.parse(localStorage.getItem('todos')|| '[]'),
    filters:['全部','未完成','已完成'],
    active:'全部'
}),
actions:{
    //修改状态
    changeDone(id){
        const todo=this.list.find(item=>item.id===id)
        todo.done=!todo.done
    },
    //删除
    delTask(id){
        this.list=this.list.filter(item=>item.id !== id)
    },
    //添加
    addTask(taskname){
        this.list.push({
            id:Date.now(),
            name:taskname,
            done:false
        })
    },
    //全选
    changeAll(e){
        this.list.forEach(item=>item.done=e.target.checked)
    },
    //清除已完成
    clearDone(){
        this.list=this.list.filter(item=>!item.done)
    },
    //点击状态
    changeActive(active){
        this.active=active
    }

},
getters:{

    isAll(){
        return this.list.every(item=>item.done)
    },
    leftCount(){
        return this.list.filter(item=>!item.done).length
    },
    showList(){
        if(this.active==='已完成'){
            return this.list.filter(item=>item.done)
        }else if(this.active==='未完成'){
            return this.list.filter(item=>!item.done)
        }else{
            return this.list
        }
    }
}
    
})
export default userTodosStore

App.vue

html 复制代码
<script setup>
import TodoHeader from './components/TodoHeader.vue'
import TodoMain from './components/TodoMain.vue'
import TodoFooter from './components/TodoFooter.vue'
</script>

<template>
  <section class="todoapp">
    <TodoHeader></TodoHeader>
    <TodoMain></TodoMain>
    <TodoFooter></TodoFooter>
  </section>
</template>

<style></style>

TodoMain.vue

html 复制代码
<script setup>
import userTodosStore from '../store/todos'
// import {watch} from 'vue'
//获取store对象
const todos=userTodosStore()
//$subscribe 作用是监视store数据的变化,变化后会触发回调函数执行

// watch(todos.list,()=>{
//   localStorage.setItem('todos',JSON.stringify(todos.list))
// })
todos.$subscribe(()=>{
  localStorage.setItem('todos',JSON.stringify(todos.list))
})




</script>

<template>
  <section class="main">
    <input @change="todos.changeAll($event)" :checked="todos.isAll" id="toggle-all" class="toggle-all" type="checkbox" />
    <label for="toggle-all">Mark all as complete</label>
    <ul class="todo-list">
      <li v-for="item in todos.showList" :key="item.id" :class="{completed:item.done}">
        <div class="view">
          <input class="toggle" type="checkbox" :checked="item.done"
          @change="todos.changeDone(item.id)"
          />
          <label>{{ item.name }}</label>
          <button class="destroy" @click="todos.delTask(item.id)"></button>
        </div>
        <input class="edit" value="Create a TodoMVC template" />
      </li>
      <!-- <li>
        <div class="view">
          <input class="toggle" type="checkbox" />
          <label>Buy a unicorn</label>
          <button class="destroy"></button>
        </div>
        <input class="edit" value="Rule the web" />
      </li> -->
    </ul>
  </section>
</template>

<style lang="less" scoped></style>

ToDoHeader.vue

html 复制代码
<script setup>
import {ref} from 'vue'
import userTodosStore from '../store/todos'

//获取store对象
const todos=userTodosStore()
const taskname=ref('')
const hKeydown=()=>{
if(taskname.value.length===0)return

  todos.addTask(taskname.value)
  taskname.value=''
}
</script>


<template>
  <header class="header">
    <h1>todos</h1>
    <input class="new-todo" 
    placeholder="What needs to be done?" 
    autofocus 
    v-model.trim="taskname"
    @keydown.enter="hKeydown"
    />
  </header>
</template>

<style lang="less" scoped></style>

ToDoFooter.vue

html 复制代码
<script setup>
import userTodosStore from '@/store/todos';
const todos=userTodosStore()

</script>

<template>
  <footer class="footer">
    <span class="todo-count">还有<strong>{{todos.leftCount}}</strong> 个未完成</span>
    <ul class="filters">
      <li v-for="item in todos.filters" :key="item">
        <a @click="todos.changeActive(item)" :class="{selected:item === todos.active}" >{{item}}</a>
      </li>
      <!-- <li>
        <a href="#/active">Active</a>
      </li>
      <li>
        <a href="#/completed">Completed</a>
      </li> -->
    </ul>
    <button class="clear-completed " @click="todos.clearDone">清除已完成</button>
  </footer>
</template>

<style lang="less" scoped></style>
相关推荐
喵叔哟7 分钟前
重构代码中引入外部方法和引入本地扩展的区别
java·开发语言·重构
狸克先生10 分钟前
如何用AI写小说(二):Gradio 超简单的网页前端交互
前端·人工智能·chatgpt·交互
尘浮生13 分钟前
Java项目实战II基于微信小程序的电影院买票选座系统(开发文档+数据库+源码)
java·开发语言·数据库·微信小程序·小程序·maven·intellij-idea
sinat_3842410913 分钟前
在有网络连接的机器上打包 electron 及其依赖项,在没有网络连接的机器上安装这些离线包
javascript·arcgis·electron
baiduopenmap25 分钟前
百度世界2024精选公开课:基于地图智能体的导航出行AI应用创新实践
前端·人工智能·百度地图
hopetomorrow27 分钟前
学习路之PHP--使用GROUP BY 发生错误 SELECT list is not in GROUP BY clause .......... 解决
开发语言·学习·php
loooseFish33 分钟前
小程序webview我爱死你了 小程序webview和H5通讯
前端
小牛itbull36 分钟前
ReactPress vs VuePress vs WordPress
开发语言·javascript·reactpress
请叫我欧皇i1 小时前
html本地离线引入vant和vue2(详细步骤)
开发语言·前端·javascript
533_1 小时前
[vue] 深拷贝 lodash cloneDeep
前端·javascript·vue.js