这两周是实践周,跟着老师做点东西

相对简单的是,用 vue 框架做一个简单的待办清单

# 步骤

结合 bootstrap 框架做了如下待办清单

首先用 npm 新建一个项目(需要 npm)

npm init vite-app todolist
//安装需要的依赖
npm install
//启动
npm run dev

其中,Bootstrap 需要从官方下载(可 git clone)

https://github.com/twbs/bootstrap/releases/download/v4.6.2/bootstrap-4.6.2-dist.zip

结构
todolist
--node_modules //依赖库
--public
--src
----assets //Bootstrap放这
----components //存放部件
------todoButton.vue //todolist的按钮
------todoInput.vue //todolist的输入
------todoList.vue //todolist的列表
----App.vue // 主界面
----index.css
----main.js // 启动入口
--...

todoButton.vue

<template>
	<div class="btn-group" role="group" aria-label="Basic example">
		<button type="button" class="btn" :class="active === 0 ? 'btn-primary' : btn-secondary"
			@click="changeActive(0)">全部</button>
		<button type="button" class="btn" :class="active === 1 ? 'btn-primary' : btn-secondary"
			@click="changeActive(1)">已完成</button>
		<button type="button" class="btn" :class="active === 2 ? 'btn-primary' : btn-secondary"
			@click="changeActive(2)">未完成</button>
	</div>
</template>

<script>
	export default {
		name: "todoButton",
		data() {
			return {
				active: 0,
			};
		},
		emits: ["changeActive"],
		methods: {
			changeActive(index) {
				this.active = index;
				this.$emit("changeActive", index);
			},
		},
	};
</script>

<style scoped>
	.btn-group {
		width: 20%;
		margin: 20px auto;
	}
</style>

todoInput.vue

<template>
	<div class="input-group mb-3">
		<div class="input-group-prepend">
			<button class="btn-primary" @click="onsubmit">提交</button>
		</div>
		<input type="text" class="form-control" placeholder="添加任务" aria-label="Username" aria-describedby="basic-addon1"
			v-model="taskname">
	</div>
</template>

<script>
	export default {
		name: "todoInput",
		data() {
			return {
				taskname: "",
			};
		},
		emits: ["addTask"],
		methods: {
			onsubmit() {
				this.$emit("addTask", this.taskname);
				this.taskname = "";
			}
		},
	};
</script>

<style scoped>
	.input-group {
		width: 40%;
		margin: 20px auto;
	}
</style>

todoList.vue

<template>
	<ul class="list-group">
		<li class="list-group-item d-flex justify-content-between align-items-center" v-for="item in todolist" :
			key="item.id">
			<!-- 复选框 -->
			<div class="form-check">
				<input class="form-check-input" type="checkbox" value="" :id="item.id" v-model="item.isCompleted">
				<label class="form-check-label" :for="item.id" :class="item.isCompleted ? 'delete' : ''">
					{{ item.task }}
				</label>
			</div>
			<span class="badge badge-success badge-pill" v-if="item.isCompleted">已完成</span>
			<span class="badge badge-warning badge-pill" v-else>未完成</span>
		</li>
	</ul>
</template>

<script>
	export default {
		name: 'todoList',
		props: {
			todolist: {
				type: Array,
				required: true,
				default: [],
			}
		}
	}
</script>

<style scoped>
	.list-group {
		width: 40%;
		margin: 20px auto;
	}

	.delete {
		text-decoration: line-through;
	}
</style>

App.vue

<template>
	<div id="app">
		<h1>TodoList</h1>
		<h6>edit by Chen</h6>
		<!-- @ 用于处理事件,而 : 用于处理属性绑定。这两个符号都是Vue.js中的常见语法糖,使代码更简洁易读 -->
		<!-- @ 符号是 v-on 指令的缩写。它用于监听DOM事件并触发相应的Vue实例中的方法。 -->
		<!-- : 符号是 v-bind 指令的缩写。它用于动态绑定属性或表达式 -->
		<!-- 查自chatgpt 2023/12/11 -->
		<todoInput @addTask="addTask"></todoInput>
		<todoList :todolist="todoList"></todoList>
		<todoButton @changeActive="changeActive"></todoButton>
	</div>
</template>

<script>
	import todoList from './components/todoList.vue'
	import todoButton from './components/todoButton.vue'
	import todoInput from './components/todoInput.vue'

	export default {
		name: "App",
		data() {
			return {
				// 假数据
				todoList: [{
						id: 1,
						task: '吃饭',
						isCompleted: true
					},
					{
						id: 2,
						task: '嘻嘻嘻',
						isCompleted: false
					},
					{
						id: 3,
						task: 'zzzzzzzz',
						isCompleted: true
					},
				],
				active: 0,
			};
		},
		computed: {
			todoList() {
				if (this.active === 0) {
					return this.todoList;
				} else if (this.active === 1) {
					return this.todoList.filter(item => item.isCompleted);
				} else {
					return this.todoList.filter(item => !item.isCompleted);
				}
			}
		},
		methods: {
			changeActive(active) {
				this.active = active;
				console.log(this.active);
			},
			addTask(taskname) {
				this.todoList.push({
					id: this.todoList.length + 1,
					task: taskname,
					isCompleted: false,
				})
			},
		},
		components: {
			todoList,
			todoButton,
			todoInput
		}
	}
</script>

main.vue

import { createApp } from 'vue'
import App from './App.vue'
import './assets/css/bootstrap.css'
import './index.css'

createApp(App).mount('#app')

Edited on