console
import { createApp } from 'https://ax.minicg.com/pvue.es.js'
const { log, dir, table, clear, warn, error } = console; clear();
createApp({
currentId: null,
filterType: 'all',
cache: null,
todos: [
{ id: 1, title: '待办清单', done: true },
{ id: 2, title: '@wavef', done: false },
{ id: 3, title: 'ax.minicg.com', done: false },
],
add(task) {
if (!task || task==='') return
const maxId = Math.max(...this.todos.map(n=>n.id))
this.todos.push({
id: maxId + 1,
title: task,
done: false
})
},
remove (item) {
this.todos.splice(this.todos.indexOf(item), 1)
},
edit (item) {
this.currentId = item.id;
this.cache = item.title;
},
done (item) {
this.currentId = null
},
cancel (item) {
this.currentId = null
item.title = this.cache
},
save() {
if (!this.inited) return
localStorage.setItem('todos', JSON.stringify(this.todos))
},
setFilterType(type) {
this.filterType = type
},
getFilterTodos() {
switch (this.filterType) {
case 'all': return this.todos
case 'done': return this.todos.filter(n => n.done===true)
case 'undone': return this.todos.filter(n => n.done===false)
}
},
mounted() {
this.inited = true
const data = localStorage.getItem('todos')
if (data) { this.todos = JSON.parse(data) }
}
}).mount()
<div v-scope @vue:mounted="mounted" class="h-full p-8 bg-white" v-cloak>
<div class="text-gray-800">
<h2 class="text-2xl font-medium mb-6">PetiteVue - 待办清单</h2>
<div class="flex justify-between text-sm text-white">
<button class="py-2 px-4 bg-green-500 !outline-none clickable" @click="add(prompt('新增待办',''))">添加</button>
<div class="flex gap-2 items-center text-sm text-black">
<span>过滤:</span>
<select class="pl-2 pr-12 border-0 bg-gray-100 text-sm rounded" @change="setFilterType($el.value)">
<option value="all">全部</option>
<option value="undone">未完成</option>
<option value="done">已完成</option>
</select>
</div>
</div>
<ul class="flex flex-col my-6 font-mono" v-effect="save()">
<li v-for="(item, index) in getFilterTodos()" :key="item.id" class="cursor-pointer p-2 hover:bg-gray-100">
<div class="flex justify-between">
<div class="w-full flex items-center gap-3">
<input type="checkbox" v-model="item.done" class="focus:ring-0">
<div v-if="item.id!==currentId" :class="['flex-1', {'line-through':item.done}]" @click="item.done=!item.done">{{item.title}}</div>
<input v-else v-effect="if(item.id===currentId)$el.focus()" type="text" v-model="item.title" class="w-full" @blur="done(item)" @keyup.enter="done(item)" @keyup.escape="cancel(item)">
</div>
<button class="text-blue-500 text-xl px-2 clickable hover:text-white hover:bg-blue-500 ml-1" @click="edit(item)">✎</button>
<button class="text-red-500 text-xl px-2 clickable hover:text-white hover:bg-red-500 ml-1" @click="remove(item)">×</button>
</div>
</li>
</ul>
</div>
</div>
<style type="postcss">
.clickable {
@apply !outline-none rounded cursor-pointer duration-200 hover:brightness-110 active:brightness-75;
}
</style>
html, body {
height: 100%;
}
[v-cloak] {
display: none;
}