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>