mirror of https://github.com/vuejs/core.git
feat(playground): todo mvc
This commit is contained in:
parent
359a5dab19
commit
0255505b5d
|
@ -7,6 +7,7 @@
|
|||
"build": "node ./setup/vite.js build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vueuse/core": "^10.7.2",
|
||||
"vue": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from 'vue/vapor'
|
||||
|
||||
import { computed } from 'vue/vapor'
|
||||
import { useLocalStorage } from '@vueuse/core'
|
||||
interface Task {
|
||||
title: string
|
||||
completed: boolean
|
||||
}
|
||||
const tasks = ref<Task[]>([])
|
||||
const value = ref('hello')
|
||||
|
||||
const tasks = useLocalStorage<Task[]>('tasks', [])
|
||||
const value = useLocalStorage('value', '')
|
||||
|
||||
const remaining = computed(() => {
|
||||
return tasks.value.filter(task => !task.completed).length
|
||||
})
|
||||
|
||||
function handleAdd() {
|
||||
tasks.value.push({
|
||||
|
@ -16,31 +21,76 @@ function handleAdd() {
|
|||
// TODO: clear input
|
||||
value.value = ''
|
||||
}
|
||||
|
||||
function handleComplete(index: number, evt: Event) {
|
||||
tasks.value[index].completed = (evt.target as HTMLInputElement).checked
|
||||
}
|
||||
|
||||
function handleClearComplete() {
|
||||
tasks.value = tasks.value.filter(task => !task.completed)
|
||||
}
|
||||
|
||||
function handleClearAll() {
|
||||
tasks.value = []
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>todos</h1>
|
||||
<ul>
|
||||
<!-- TODO: v-for -->
|
||||
<li>
|
||||
<!-- TODO checked=false -->
|
||||
<input type="checkbox" :checked="tasks[0]?.completed" />
|
||||
<li v-show="tasks[0]" :class="{ del: tasks[0]?.completed }">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="tasks[0]?.completed"
|
||||
@change="handleComplete(0, $event)"
|
||||
/>
|
||||
{{ tasks[0]?.title }}
|
||||
</li>
|
||||
<li>
|
||||
<input type="checkbox" :checked="tasks[1]?.completed" />
|
||||
<li v-show="tasks[1]" :class="{ del: tasks[1]?.completed }">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="tasks[1]?.completed"
|
||||
@change="handleComplete(1, $event)"
|
||||
/>
|
||||
{{ tasks[1]?.title }}
|
||||
</li>
|
||||
<li>
|
||||
<input type="checkbox" :checked="tasks[2]?.completed" />
|
||||
<li v-show="tasks[2]" :class="{ del: tasks[2]?.completed }">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="tasks[2]?.completed"
|
||||
@change="handleComplete(2, $event)"
|
||||
/>
|
||||
{{ tasks[2]?.title }}
|
||||
</li>
|
||||
<li>
|
||||
<input type="checkbox" :checked="tasks[3]?.completed" />
|
||||
<li v-show="tasks[3]" :class="{ del: tasks[3]?.completed }">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="tasks[3]?.completed"
|
||||
@change="handleComplete(3, $event)"
|
||||
/>
|
||||
{{ tasks[3]?.title }}
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" v-model="value" />
|
||||
<button @click="handleAdd">Add</button>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
{{ remaining }} item{{ remaining !== 1 ? 's' : '' }} left /
|
||||
{{ tasks.length }} item{{ tasks.length !== 1 ? 's' : '' }} in total
|
||||
</p>
|
||||
<div style="display: flex; gap: 8px">
|
||||
<input
|
||||
type="text"
|
||||
v-model="value"
|
||||
@keydown.enter="handleAdd"
|
||||
placeholder="What need to be done?"
|
||||
/>
|
||||
<button @click="handleAdd">Add</button>
|
||||
<button @click="handleClearComplete">Clear completed</button>
|
||||
<button @click="handleClearAll">Clear all</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.del {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -6,6 +6,9 @@ import * as CompilerVapor from '@vue/compiler-vapor'
|
|||
import * as CompilerSFC from '@vue/compiler-sfc'
|
||||
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
alias: [{ find: /^vue$/, replacement: 'vue/vapor' }],
|
||||
},
|
||||
build: {
|
||||
target: 'esnext',
|
||||
},
|
||||
|
@ -20,4 +23,7 @@ export default defineConfig({
|
|||
DevPlugin(),
|
||||
Inspect(),
|
||||
],
|
||||
optimizeDeps: {
|
||||
exclude: ['@vueuse/core'],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -454,6 +454,9 @@ importers:
|
|||
|
||||
playground:
|
||||
dependencies:
|
||||
'@vueuse/core':
|
||||
specifier: ^10.7.2
|
||||
version: 10.7.2(vue@packages+vue)
|
||||
vue:
|
||||
specifier: workspace:*
|
||||
version: link:../packages/vue
|
||||
|
@ -1346,6 +1349,10 @@ packages:
|
|||
resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==}
|
||||
dev: true
|
||||
|
||||
/@types/web-bluetooth@0.0.20:
|
||||
resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
|
||||
dev: false
|
||||
|
||||
/@types/yauzl@2.10.2:
|
||||
resolution: {integrity: sha512-Km7XAtUIduROw7QPgvcft0lIupeG8a8rdKL8RiSyKvlE7dYY31fEn41HVuQsRFDuROA8tA4K2UVL+WdfFmErBA==}
|
||||
requiresBuild: true
|
||||
|
@ -1641,6 +1648,31 @@ packages:
|
|||
resolution: {integrity: sha512-BK9D7AgpYAWVrtd7Kkc3CotU/ox8l+mPjsLgK16ZP+Ldj8jXPrJtzYQ2rTQNRJOxVSVx5acftDTLDLENFhQdDw==}
|
||||
dev: false
|
||||
|
||||
/@vueuse/core@10.7.2(vue@packages+vue):
|
||||
resolution: {integrity: sha512-AOyAL2rK0By62Hm+iqQn6Rbu8bfmbgaIMXcE3TSr7BdQ42wnSFlwIdPjInO62onYsEMK/yDMU8C6oGfDAtZ2qQ==}
|
||||
dependencies:
|
||||
'@types/web-bluetooth': 0.0.20
|
||||
'@vueuse/metadata': 10.7.2
|
||||
'@vueuse/shared': 10.7.2(vue@packages+vue)
|
||||
vue-demi: 0.14.6(vue@packages+vue)
|
||||
transitivePeerDependencies:
|
||||
- '@vue/composition-api'
|
||||
- vue
|
||||
dev: false
|
||||
|
||||
/@vueuse/metadata@10.7.2:
|
||||
resolution: {integrity: sha512-kCWPb4J2KGrwLtn1eJwaJD742u1k5h6v/St5wFe8Quih90+k2a0JP8BS4Zp34XUuJqS2AxFYMb1wjUL8HfhWsQ==}
|
||||
dev: false
|
||||
|
||||
/@vueuse/shared@10.7.2(vue@packages+vue):
|
||||
resolution: {integrity: sha512-qFbXoxS44pi2FkgFjPvF4h7c9oMDutpyBdcJdMYIMg9XyXli2meFMuaKn+UMgsClo//Th6+beeCgqweT/79BVA==}
|
||||
dependencies:
|
||||
vue-demi: 0.14.6(vue@packages+vue)
|
||||
transitivePeerDependencies:
|
||||
- '@vue/composition-api'
|
||||
- vue
|
||||
dev: false
|
||||
|
||||
/@zeit/schemas@2.29.0:
|
||||
resolution: {integrity: sha512-g5QiLIfbg3pLuYUJPlisNKY+epQJTcMDsOnVNkscrDP1oi7vmJnzOANYJI/1pZcVJ6umUkBv3aFtlg1UvUHGzA==}
|
||||
dev: true
|
||||
|
@ -6284,6 +6316,21 @@ packages:
|
|||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/vue-demi@0.14.6(vue@packages+vue):
|
||||
resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==}
|
||||
engines: {node: '>=12'}
|
||||
hasBin: true
|
||||
requiresBuild: true
|
||||
peerDependencies:
|
||||
'@vue/composition-api': ^1.0.0-rc.1
|
||||
vue: ^3.0.0-0 || ^2.6.0
|
||||
peerDependenciesMeta:
|
||||
'@vue/composition-api':
|
||||
optional: true
|
||||
dependencies:
|
||||
vue: link:packages/vue
|
||||
dev: false
|
||||
|
||||
/w3c-xmlserializer@5.0.0:
|
||||
resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
|
||||
engines: {node: '>=18'}
|
||||
|
|
Loading…
Reference in New Issue