用一个 TodoList 入门 Vue3 和一些新技术

1,110 阅读1分钟

「这是我参与2022首次更文挑战的第19天,活动详情查看:2022首次更文挑战」。

用到技术

  • pnpm
  • vite
  • typescript
  • vue3

写一个 TodoList,可以逐渐熟悉 Vue3 中这些知识:

  • script setup
  • ref
  • computed
  • 条件渲染和列表渲染
  • 数据绑定和 v-model
  • 事件

本文不讲解 Vue3 基础知识,初学者需结合 Vue3 文档食用。

项目安装

pnpm 的安装很简单,就一行命令:

npm i -g pnpm

使用 pnpm 新建一个 vite 项目

pnpm create vite my-v3-app -- --template vue

然后进入项目,安装依赖,启动

cd my-v3-app
pnpm i
pnpm dev

image.png

真的太快了,全程不到一分钟,就可以开始开发了。

做个对比吧,vite 的默认依赖安装,使用 npm 要花 7s,使用 pnpm 只花 122ms。

image.png

image.png

script setup

我们写一个简单的计数器功能来感受一下 script setup

addCount.gif 不用 script setup

<template>
  <p>{{count}}</p>
  <button @click="handleAdd">+</button>
</template>

<script lang='ts'>

import { defineComponent, ref } from 'vue'

export default defineComponent({
  setup() {
    const count = ref<number>(0)
    const handleAdd = () => {
      count.value++
    }
    return {
      handleAdd,
      count
    }
  }
})
</script>

用 script setup

<template>
  <p>{{count}}</p>
  <button @click="handleAdd">+</button>
</template>

<script lang='ts' setup>
import { ref } from 'vue'

const count = ref<number>(0)
const handleAdd = () => {
  count.value++
}

很明显,代码量少很多,不用定义 setup,也不用 return 变量了,很方便。

TodoList 功能

  • 新增待办事项
  • 删除待办事项
  • 全选和取消全选功能
  • 清理已做事项

todolist.gif

代码实现

<template>
  <input type="text" v-model="todoMsg">
  <button @click="add">添加</button>
  <button @click="clearHasDone">清理</button>
  <div v-if="lists.length">
    <div v-for="(item, index) in lists" :key="item.msg">
      <input type="checkbox" v-model="item.done">
      <span :class="{done: item.done}">{{item.msg}}</span>
      <span class="delete-icon" @click="deleteItem(index)"></span>
    </div>
  <div>
    <span>全选</span>
    <input type="checkbox" v-model="isAllDone">
    <span>{{hasDone}} / {{lists.length}}</span>
  </div>
  </div>
  <div v-else>暂无数据</div>
  
  
</template>

<script lang='ts' setup>

import { ref, computed } from 'vue';

interface TodoItem {
  msg: string
  done: boolean
}

const todoMsg = ref<string>('')

const lists = ref<TodoItem[]>([
  { msg: '吃饭', done: true},
  { msg: '睡觉', done: false},
  { msg: '打游戏', done: false}
])

const hasDone = computed(() => lists.value.filter(item => item.done).length)

const isAllDone = computed<boolean>({
  get() {
    return hasDone.value === lists.value.length
  },
  set(value:boolean) {
    lists.value.forEach(item => {
      item.done = value
    })
  }
}) 

const add = () => {
  if (todoMsg.value) {
    lists.value.push({
    msg: todoMsg.value,
    done: false
  })
  todoMsg.value = ''
  }
}

const deleteItem = (index:number) => {
  lists.value.splice(index, 1)
}

const clearHasDone = () => {
  lists.value = lists.value.filter(item => !item.done)
}
</script>

<style>
.done {
  text-decoration: line-through;
  color: gray;
}
.delete-icon {
  cursor: pointer;
}
</style>

小结

如果是 Vue3 初学者,通过一个 TodoList demo 的编写,可以体会日常开发中写得最多的增删改查,还能在实现功能的同时去攻克 Vue3 的一些语法,确实是非常好的一个入门 Vue3 的方式。