store/todos.js
//导入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
<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
<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
<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)returntodos.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
<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>