
需求文档
需求解析
使用 VSCode 打开项目目录
D:\vue\chapter02\learning_schedule清除默认样式
删除src\style.css中的所有样式代码。引入 Bootstrap
在index.html中引入:html
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">修改 App.vue 默认内容
vue
<template> 学习计划表 </template>
2.1.2 渲染表格区域数据
定义数据
js
import { ref } from 'vue' const list = ref([ { id: '1', subject: 'Vue.js前端实战开发', content: '学习指令,例如v-if、v-for、v-model等', place: '自习室', status: false, } ])表格结构
使用 Bootstrap 的table样式类,包含:序号、学习科目、学习内容、学习地点、完成状态、操作列。循环渲染与状态切换
- 使用
v-for渲染表格行,:key绑定item.id。 - 完成状态列使用
switch开关样式,v-model绑定item.status。 - 通过
v-if/v-else显示“已完成”或“未完成”。 - “删除”按钮用于删除该行计划。
- 使用
2.1.3 实现学习计划的删除功能
绑定点击事件
html
<a href="javascript:;" @click="remove(item.id, item.status)">删除</a>实现删除方法
js
let remove = (id, status) => { if (status) { list.value = list.value.filter(item => item.id !== id) } else { alert('请完成该学习计划后再进行删除操作!') } }- 只有完成状态为“已完成”(
status === true)时才能删除。
- 只有完成状态为“已完成”(
2.1.4 实现学习计划的添加功能
定义表单相关数据
js
let subject = ref('') let content = ref('') let nextId = ref('') let selectedOption = ref('自习室') let options = ref([ { placeCode: 0, place: '自习室' }, { placeCode: 1, place: '图书馆' }, { placeCode: 2, place: '宿舍' } ])卡片区域结构
- 卡片标题:学习计划表
- 表单包含:学习科目(文本框)、学习内容(多行文本框)、学习地点(下拉框)、添加按钮。
表单控件绑定与修饰符
- 使用
v-model.trim绑定输入值,自动去除首尾空格。 - 下拉框
v-model绑定selectedOption,选项通过v-for动态渲染。
- 使用
表单提交事件
html
<form @submit.prevent="add">添加方法实现
js
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.1.5 实现状态的切换功能
问题:点击
<label>文字时无法切换对应行的完成状态。解决:动态生成
id和for属性,关联input与label。html
<input :id="'cb' + item.id" v-model="item.status" ... /> <label :for="'cb' + item.id" v-if="item.status">已完成</label> <label :for="'cb' + item.id" v-else>未完成</label>
总结
本案例实现了一个基于 Vue 3 + Bootstrap 的“学习计划表”应用,涵盖以下功能:
- 表格数据的动态渲染
- 学习计划的新增与删除
- 完成状态的切换与样式联动
- 表单输入的双向绑定与修饰符使用
通过该案例,实践了 v-for、v-if、v-model、事件绑定、修饰符等 Vue 核心指令与功能。
最后代码
首先要在index.html中引入以下样式资源

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"><script setup>
import { ref } from 'vue'
const list = ref([
{
id: '1',
subject: 'Vue.js前端实战开发',
content: '学习指令,例如v-if、v-for、v-model等',
place: '自习室',
status: false,
}
])
const subject = ref('')
const content = ref('')
const nextId = ref('')
const selectedOption = ref('自习室')
const options = ref([
{ placeCode: 0, place: '自习室' },
{ placeCode: 1, place: '图书馆' },
{ placeCode: 2, place: '宿舍' }
])
const remove = (id, status) => {
if (status) {
list.value = list.value.filter(item => item.id !== id)
} else {
alert('请完成该学习计划后再进行删除操作!')
}
}
const add = () => {
if (subject.value === '') {
alert('学习科目为必填项!')
return
}
const maxId = list.value.length > 0 ? Math.max(...list.value.map(item => Number(item.id))) : 0
nextId.value = maxId + 1
const obj = {
id: nextId.value.toString(),
subject: subject.value,
content: content.value,
place: selectedOption.value,
status: false,
}
list.value.push(obj)
subject.value = ''
content.value = ''
selectedOption.value = '自习室'
}
</script>
<template>
<div class="container mt-4">
<div class="card">
<div class="card-header">
<h5>学习计划表</h5>
</div>
<div class="card-body">
<form @submit.prevent="add" class="mb-4">
<div class="row g-3">
<div class="col-md-3">
<input type="text" class="form-control" v-model.trim="subject" placeholder="学习科目">
</div>
<div class="col-md-5">
<textarea class="form-control" v-model.trim="content" placeholder="学习内容" rows="1"></textarea>
</div>
<div class="col-md-2">
<select class="form-select" v-model="selectedOption">
<option v-for="option in options" :key="option.placeCode" :value="option.place">{{ option.place }}</option>
</select>
</div>
<div class="col-md-2">
<button type="submit" class="btn btn-primary w-100">添加</button>
</div>
</div>
</form>
<table class="table table-bordered table-hover">
<thead class="table-light">
<tr>
<th>序号</th>
<th>学习科目</th>
<th>学习内容</th>
<th>学习地点</th>
<th>完成状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in list" :key="item.id">
<td>{{ index + 1 }}</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" :id="'cb' + item.id" v-model="item.status">
<label class="form-check-label" :for="'cb' + item.id" v-if="item.status">已完成</label>
<label class="form-check-label" :for="'cb' + item.id" v-else>未完成</label>
</div>
</td>
<td>
<a href="javascript:;" class="text-danger" @click="remove(item.id, item.status)">删除</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>