vue.js——学习计划表

1)准备工作

①打开D:\vue\chapter02\ learning_schedule 目录,找到 index.html 文件。

在文件中引 入BootStrap 样式文件,具体代码如下

复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.ico" />
	<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite App</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

上述代码中,第6行代码引入Bootstrap的CSS文件,引用后即可使用Bootstrap快速 开发响应式网页,使用全局CSS样式美化标签。

②修改src\App.vue文件中的默认内容,具体如图所示:

至此,"学习计划表"案例准备工作已完成。

2)渲染表格区域数据

接下来正式进入"学习计划表"案例的开发。在App组件中编写表格区域的页面结构和样式,并在页面上渲染表格数据,具体实现步骤如下。

① 在<script setup>标签中定义渲染表格所需的数据,具体代码如下

复制代码
<script setup>
	import {ref} from 'vue'
	const list =ref([
		{
			id:'1',
			subject:'Vue.js前端实战开发',
			content:'学习指令,例如v-if、v-for、v-model等',
			place:'自习室',
			status:false,
		},
	])
</script>

上述代码中,list数组表示渲染表格区域所需的数据,id属性表示序号,subject属性表示学习科目,content属性表示学习内容,place属性表示学习地点,status属性表示学习计划的完成状态,若属性值为false,表示"未完成",若属性值为true表示"已完成"。

② 根据Bootstrap文档找到Tables,根据实际需要合适的样式,本案例中表格的结构样式具体如下。

复制代码
<template>
<table class="table table-striped table-hover table-bordered">
		<thead>
			<tr>
				<th scope="col">序号</th>
				<th scope="col">学习科目</th>
				<th scope="col">学习内容</th>
				<th scope="col">学习地点</th>
				<th scope="col">完成状态</th>
				<th scope="col">操作</th>
			</tr>
		</thead>
</table>
</template>

③ 接下来通过v-for指令循环渲染表格行的数据,代码如下:

复制代码
<tbody>
			<tr v-for="item in list" :key="item.id">
				<td>{{item.id}}</td>
				<td>{{item.subject}}</td>
				<td>{{item.content}}</td>
				<td>{{item.place}}</td>
				<td>
					<div class="form-check form-switch">
						<input class="form-check-input" type="checkbox" role="switch" id="'cd' + item.id" v-model="item.status" />
						<label class="form-check-label" for="'cd' + item.id" v-if="item.status">已完成</label>
						<label class="form-check-label" for="'cd' + item.id" v-else>未完成</label>
					</div>
				</td>
            </tr>
</tbody>

第2~15行代码通过v-for指令渲染表格行,将list数组中的数据渲染到 页面上,每项必须提供一个唯一key值;第3~6行代码将列表项中序号、学习科目、学习内容、学习地点通过Mustache语法渲染到页面上;第7~13行代码将表格行渲染为 switch 开关效果,其中,第8行代码将标签渲染为开关的效果,通过v-model指令 绑定绑定data中的list数组中每个对象的status属性,第10~11行代码通过v-if、v-else 条件渲染指令根据status属性的属性值渲染"已完成"或"未完成"的标签。

3) 实现学习计划的删除功能

在单击表格行最后一列"删除"时,可以对整行的学习计划进行删除操作。在实现该功能时,在单击"删除"时,传递该行数据所对应的id属性,通过调用数组中的 filter()方法实现数据的过滤。在删除学习计划时,如果完成状态为"未完成"时禁止删 除,完成状态为"已删除"时该学习计划可以进行删除操作。实现学习计划删除功能的 具体步骤如下。

① 添加标签、单击事件,具体代码如下:
复制代码
<a href="javascript:;" @click="remove(item.id, item.status)">删除</a>
② 在<script setup>标签中编写remove()方法,对学习计划完成状态的判断,具体代码如下。
复制代码
let remove=(id,status) =>{
		if(status) {
			list.value=list.value.filter(item=>item.id !== id)
		}else{
			alert('请完成该学习计划后再进行删除操作!')
		}
	}

至此,学习计划表的删除功能已实现。

4)实现学习计划的添加功能

该功能通过表单来进行实现,在单击"添加"按钮时实现表单中所有信息的提交, 进行添加学习计划的操作。实现学习计划的添加功能具体实现步骤如下。

① 首先在<script setup>标签中定义页面所需的数据,具体代码如下

复制代码
let subject=ref('')
	let content=ref('')
	let nextId=ref('')
	let selectedOption=ref('自习室')
	let options = ref([
		{ placeCode: 0, place: '自习室'},
		{ placeCode: 1, place: '图书馆'},
		{ placeCode: 2, place: '宿舍'},
	])

上述代码中,第1行代码定义了subject,表示学习科目;第2行代码定义了content, 表示学习内容;第3行代码定义了nextId,表示新添加数据的id;第4行代码定义了默认 选中的学习地点;第5~9行代码定义了options数组,表示学习地点,其中placeCode属性 表示地点编号,place属性表示地点名称。

② 添加学习科目区域的页面结构,具体代码如下。

复制代码
<div class="col-auto">
						<div class="input-group mb-3">
							<span class="input-group-text" id="basic-addon1">学习科目</span>
							<input type="text" class="form-control" placeholder="请输入学习科目" v-model.trim="subject"/>
						</div>
					</div>

上述代码中,第2~5行代码定义了学习科目区域,通过标签定义的文本框可 以输入学习科目,通过v-model指令,将标签与subject实现数据的双向绑定,即当更改文本框中的值时subject的值更改。同时为v-model指令添加了trim修饰符,用于自动过滤用户输入的首尾空白字符。

③ 添加学习任务区域的页面结构,具体代码如下。

复制代码
<div class="col-auto">
						<div class="input-group mb-3">
							<span class="input-group-text" id="basic-addon1">学习内容</span>
							<textarea class="form-control" v-model.trim="content" placeholder="请输入学习内容" :style="{ height:'32px'}"></textarea>
						</div>
					</div>

上述代码中,第2~5行代码定义了学习内容区域,通过标签定义的多行文 本框可以输入学习内容,通过v-model指令与content绑定,实现视图与数据的双向绑 定。同时为v-model指令添加了trim修饰符,用于自动过滤用户输入的首尾空白字符。

④ 添加学习地点区域的页面结构,具体代码如下。

复制代码
<div class="col-auto">
						<div class="input-group mb-3">
							<span class="input-group-text" id="basic-addon1">学习地点</span>
							<select class="from-select form-select-sm" v-model="selectedOption">
								<option v-for="option in options" :value="option.place" :key="option.placeCode">
									{{option.place}}
								</option>
							</select>
						</div>
					</div>

上述代码中,第2~9行代码定义了学习地点区域,其中,第4~8行代码通过标签定义了下拉列表,通过v-model指令与selectedOption绑定,实现数据的双向绑定。 如果v-model指令的初始值不匹配任何一个选项,标签会渲染成未选择的状态, 所以selectedOption 属性值为"自习室",表示标签的初始值为"自习室",自习室为下拉列表中定义的一个值。第5~7行代码通过v-for条件渲染指令实现学习地点的渲染,当下拉列表中选项改变时,selectedOption属性更改。

⑤ 为<form>标签添加submit事件,实现单击"添加"按钮时添加信息,具体代码如下。

复制代码
<form @submit.prevent="add">
......
</form>

添加事件处理函数为add(),同时为submit 事件添加事件修饰符prevent,用来阻止表单的默认提交行为。实现在单击按钮后提交表单,执行add()方法。

⑥ 在<script setup>标签中编写add()方法,实现学习计划的添加,具体代码如下。

复制代码
let add=()=>{
		if(subject.value === '') {
			alert('学习科目为必填项')
			return
		}
		nextId.value=Math.max(...list.value.map(item => item.id)) + 1
		const obj ={
			id:nextId.value,
			subject: subject.value,
			content:content.value,
			place: selectedOption.value,
			status:false,
		}
		list.value.push(obj)
		subject.value=''
		content.value=''
		selectedOption.value='自习室'
	}

上述代码中,第2~5行代码通过if进行判断,若学习科目字段subject为空,则弹出提示,且不执行接下来的添加操作;第6行代码,通过调用max()方法,找到list数组中 id 中最大值,新添加数据的id为最大值加1;第7~13行代码为需要新添加的数据,包括 id、subject、content、place 等,在默认情况下 status 为 false,表示未完成该学习计划;第 14 行代码调用push()方法实现将obj对象添加到list数组的末尾;第15~16行代码将 subject、content 中的数据清空;第17行代码定义下拉列表的默认值。

自此,上述代码结束,完整代码如下:

复制代码
<template>
	<div class="card">
		<div class="card-header">学习机计划表</div>
		<div class="card-body">
			<form @submit.prevent="add">
				<div class="row g-4">
					<div class="col-auto">
						<div class="input-group mb-3">
							<span class="input-group-text" id="basic-addon1">学习科目</span>
							<input type="text" class="form-control" placeholder="请输入学习科目" v-model.trim="subject"/>
						</div>
					</div>
					<div class="col-auto">
						<div class="input-group mb-3">
							<span class="input-group-text" id="basic-addon1">学习内容</span>
							<textarea class="form-control" v-model.trim="content" placeholder="请输入学习内容" :style="{ height:'32px'}"></textarea>
						</div>
					</div>
					<div class="col-auto">
						<div class="input-group mb-3">
							<span class="input-group-text" id="basic-addon1">学习地点</span>
							<select class="from-select form-select-sm" v-model="selectedOption">
								<option v-for="option in options" :value="option.place" :key="option.placeCode">
									{{option.place}}
								</option>
							</select>
						</div>
					</div>
					<div class="col-auto">
						<button type="submit" class="btn btn-primary">添加</button>
					</div>
				</div>
			</form>
		</div>
	</div>
	<table class="table table-striped table-hover table-bordered">
		<thead>
			<tr>
				<th scope="col">序号</th>
				<th scope="col">学习科目</th>
				<th scope="col">学习内容</th>
				<th scope="col">学习地点</th>
				<th scope="col">完成状态</th>
				<th scope="col">操作</th>
			</tr>
		</thead>
		<tbody>
			<tr v-for="item in list" :key="item.id">
				<td>{{item.id}}</td>
				<td>{{item.subject}}</td>
				<td>{{item.content}}</td>
				<td>{{item.place}}</td>
				<td>
					<div class="form-check form-switch">
						<input class="form-check-input" type="checkbox" role="switch" id="'cd' + item.id" v-model="item.status" />
						<label class="form-check-label" for="'cd' + item.id" v-if="item.status">已完成</label>
						<label class="form-check-label" for="'cd' + item.id" v-else>未完成</label>
					</div>
				</td>
				<td>
					<a href="javascript:;" @click="remove(item.id, item.status)">删除</a>
				</td>
			</tr>
		</tbody>
	</table>
</template>

<script setup>
	import {ref} from 'vue'
	const list =ref([
		{
			id:'1',
			subject:'Vue.js前端实战开发',
			content:'学习指令,例如v-if、v-for、v-model等',
			place:'自习室',
			status:false,
		},
	])
	let remove=(id,status) =>{
		if(status) {
			list.value=list.value.filter(item=>item.id !== id)
		}else{
			alert('请完成该学习计划后再进行删除操作!')
		}
	}
	let subject=ref('')
	let content=ref('')
	let nextId=ref('')
	let selectedOption=ref('自习室')
	let options = ref([
		{ placeCode: 0, place: '自习室'},
		{ placeCode: 1, place: '图书馆'},
		{ placeCode: 2, place: '宿舍'},
	])
	let add=()=>{
		if(subject.value === '') {
			alert('学习科目为必填项')
			return
		}
		nextId.value=Math.max(...list.value.map(item => item.id)) + 1
		const obj ={
			id:nextId.value,
			subject: subject.value,
			content:content.value,
			place: selectedOption.value,
			status:false,
		}
		list.value.push(obj)
		subject.value=''
		content.value=''
		selectedOption.value='自习室'
	}
</script>

<style>
</style>

运行结果如图:

至此,"学习计划表"完成。
相关推荐
西岸行者12 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意12 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码12 天前
嵌入式学习路线
学习
毛小茛13 天前
计算机系统概论——校验码
学习
babe小鑫13 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms13 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下13 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。13 天前
2026.2.25监控学习
学习
im_AMBER13 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J13 天前
从“Hello World“ 开始 C++
c语言·c++·学习