vue基础作业实验十
- 实验要求
- 案例要点:
- 代码以及思考
- style部分
- Vue.js 部分
- Vue 实例部分
这段代码是一个基于 Vue.js 的静态页面,功能包括商品品牌的添加、删除和搜索。
实验要求
一、实验的基本内容
(1)Vue模板语法。
(2)Vue条件渲染与列表渲染。
(3)事件处理。
(4)表单输入绑定。
(5)组件基础。
二、实验的基本要求
(1)了解VUE框架的使用。
(2)掌握VUE模板语法。
(3)熟练掌握条件渲染与列表渲染。
(4)掌握表单的双向绑定。
(5)掌握事件处理设置。
(6)掌握简单组件的应用。
三、实验的基本仪器设备和耗材
计算机、VSCode
案例要点:
商品列表由已有数据渲染生成。
实现商品的添加、删除、搜索功能。
− 添加商品时,时期为当前系统日期。
− 删除商品时,弹出确认对话框,经用户确认删除后,删除商品,否则不操作。
− 能够根据商品名称的部分字词进行模糊搜索,确认搜索后,列表显示满足条件商品;退出搜索模式后,展示全部商品;如果没有符合搜索条件商品,则显示“没有商品数据”
代码以及思考
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>静态页面</title>
<style>
#app {
width: 600px;
margin: 10px auto;
}
.tb {
border-collapse: collapse;
width: 100%;
}
.tb th {
background-color: #0094ff;
color: white;
}
.tb td,
.tb th {
padding: 5px;
border: 1px solid black;
text-align: center;
}
.add-form,
.search-form {
margin-bottom: 10px;
}
.delete-btn {
color: red;
text-decoration: none;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
<div id='app'>
<div class='add-form'>
<label for="newBrandName">商品名称:</label>
<input id="newBrandName" type="text" v-model='newBrandName'>
<input type="button" value="添加" @click="addBrand">
</div>
<div class='search-form'>
<label for="search">搜索商品:</label>
<input id="search" type='text' v-model='searchQuery' placeholder="请输入搜索条件">
<input type="button" value="搜索" @click="searchBrands"> <!-- 修改此处,绑定正确的搜索方法 -->
</div>
<table class='tb'>
<tr>
<th>编号</th>
<th>品牌名称</th>
<th>创立时间</th>
<th>操作</th>
</tr>
<tr v-for="(brand, index) in filteredBrands" :key='index'>
<td>{{ index + 1 }}</td>
<td>{{ brand.brandName }}</td>
<td>{{ brand.time }}</td>
<td>
<a href="#" class="delete-btn" @click.prevent="deleBrand(index)">删除</a>
</td>
</tr>
<tr v-if="filteredBrands.length === 0">
<td colspan='4'>没有品牌数据</td>
</tr>
</table>
</div>
<script>
var brands = [
{ brandName: 'TCL', time: '2018-1-1' },
{ brandName: '小米', time: '2018-1-1' },
{ brandName: 'apple', time: '2018-1-1' }
];
new Vue({
el: '#app',
data: {
brands: brands,
newBrandName: '',
searchQuery: ''
},
computed: {
filteredBrands() {
if (this.searchQuery) {
return this.brands.filter(brand =>
brand.brandName.toLowerCase().includes(this.searchQuery.toLowerCase())
);
}
return this.brands;
}
},
methods: {
addBrand() {
this.brands.unshift({
brandName: this.newBrandName,
time: new Date().toISOString().slice(0, 10)
});
this.newBrandName = '';
},
searchBrands() {
// 这里可以根据实际需求完善更复杂的搜索逻辑,目前简单依赖计算属性的筛选
// 比如可以添加一些提示信息等逻辑处理,这里暂保持最简形式
},
deleBrand(index) {
if (confirm('确认删除吗?')) {
this.brands.splice(index, 1);
}
}
}
});
</script>
<hr>
202217020014©2024.12
</body>
</html>
效果
从整体上来看是由三部分组成
在<div id='app'></div>这
一容器里
<div class='add-form'></div>
<div class='search-form'></div>
<table class='tb'></div>
代码相关知识
表格、表单以及按钮等的样式设置
style部分
1. #app 样式
#app {
width: 600px;
margin: 10px auto;
}
#app: 选择具有 id=“app” 的 DOM 元素(即 Vue 实例挂载的容器)。
width: 600px;: 设置容器的宽度为 600px。
margin: 10px auto;: 设置容器的上下边距为 10px,左右自动居中。这样会使得容器在页面上居中显示。
回顾一下之前的知识margin: 10px auto;为什么居中
margin: 10px auto; 的作用是使元素在水平上居中,并在垂直方向上提供一定的外边距。
下面详细解释一下这段 CSS 的工作原理,margin: 10px auto; 的作用。
这个 CSS 规则分为两个部分:
10px: 设置元素上下(垂直方向)的外边距为 10px。
auto: 设置元素左右(水平)方向的外边距为 auto,这就是居中的关键。
为什么 auto 会居中
当你设置 margin-left 和 margin-right 为 auto 时,浏览器会自动计算左右边距,使得元素在父容器中水平居中。这是通过将父容器的剩余空间平均分配给左右边距来实现的。这样,元素的左右两侧就会自动对称地分布在父容器的中间。
具体情况
父容器需要有明确的宽度:为了让元素居中,父容器必须有一个明确的宽度。如果父容器的宽度是 100%(即占据整个屏幕宽度),那么 auto 会根据该父容器的宽度,计算出元素的左右外边距并使其居中。
元素本身需要有固定宽度:元素本身需要有明确的宽度,否则浏览器无法计算剩余空间来进行居中。
这里的元素是指子元素
比如说
<div class="container">
<div class="box">内容</div>
</div>
.container {
width: 600px;
background-color: lightgrey;
}
.box {
width: 200px;
margin: 10px auto; /* 垂直 10px, 水平自动居中 */
background-color: lightblue;
}
父容器 .container 的宽度是 600px。
子元素 .box 的宽度是 200px。
通过 margin: 10px auto;,auto 会使 .box 在父容器内水平居中,同时上下外边距为 10px。
2. .tb 样式
.tb {
border-collapse: collapse;
width: 100%;
}
.tb: 选择所有类名为 tb 的元素,主要用于表格。
border-collapse: collapse;: 设置表格的边框合并,去掉表格单元格之间的间隙,使得表格的边框看起来更紧凑。
width: 100%;: 设置表格的宽度为 100%,使表格适应其父容器的宽度。
没写border-collapse: collapse
写了
3. .tb th 样式
.tb th {
background-color: #0094ff;
color: white;
}
.tb th: 选择表格中的所有表头单元格()。
background-color: #0094ff;: 设置表头的背景色为蓝色 (#0094ff)。
color: white;: 设置表头文本的颜色为白色。
4. .tb td, .tb th 样式
.tb td,
.tb th {
padding: 5px;
border: 1px solid black;
text-align: center;
}
.tb td, .tb th: 选择表格中的所有单元格( 和 )。
padding: 5px;: 设置单元格的内边距为 5px,使单元格内容与边框之间有一些空隙。
border: 1px solid black;: 设置单元格的边框为 1px 的黑色实线。
text-align: center;: 设置单元格内容居中对齐。
5. .add-form, .search-form 样式
.add-form,
.search-form {
margin-bottom: 10px;
}
.add-form, .search-form: 选择所有类名为 add-form 和 search-form 的元素,分别用于品牌添加表单和品牌搜索表单。
margin-bottom: 10px;: 设置表单底部的外边距为 10px,使得每个表单之间有一定的间隔,提升页面可读性。
6. .delete-btn 样式
.delete-btn {
color: red;
text-decoration: none;
}
.delete-btn: 选择所有类名为 delete-btn 的元素,通常应用于删除按钮。
color: red;: 设置删除按钮的文本颜色为红色,强调删除操作。
text-decoration: none;: 取消删除按钮默认的下划线(假如按钮是链接的话),使得它看起来更简洁。
Vue.js 部分
<div class='add-form'>
<label for="newBrandName">商品名称:</label>
<input id="newBrandName" type="text" v-model='newBrandName'>
<input type="button" value="添加" @click="addBrand">
</div>
<label>
:为输入框提供一个标签,显示 “商品名称”。
<input id="newBrandName" type="text" v-model='newBrandName'>
:定义一个文本输入框,使用 v-model 绑定 Vue 实例中的 newBrandName 数据模型。当用户输入时,newBrandName 会自动更新。
<input type="button" value="添加" @click="addBrand">
:定义一个按钮,点击时触发 Vue 实例中的 addBrand 方法,用于添加品牌。
<div class='search-form'>
<label for="search">搜索商品:</label>
<input id="search" type='text' v-model='searchQuery' placeholder="请输入搜索条件">
<input type="button" value="搜索" @click="searchBrands">
</div>
<label>
:为输入框提供标签,显示 “搜索商品”。
<input id="search" type='text' v-model='searchQuery' placeholder="请输入搜索条件">
:定义一个文本输入框,使用 v-model 绑定 Vue 实例中的 searchQuery 数据模型。
<input type="button" value="搜索" @click="searchBrands">
:点击按钮触发 searchBrands 方法,这个方法本来是为空的,但你可以扩展它来执行更复杂的搜索。
<table class='tb'>
<tr>
<th>编号</th>
<th>品牌名称</th>
<th>创立时间</th>
<th>操作</th>
</tr>
<tr v-for="(brand, index) in filteredBrands" :key='index'>
<td>{{ index + 1 }}</td>
<td>{{ brand.brandName }}</td>
<td>{{ brand.time }}</td>
<td>
<a href="#" class="delete-btn" @click.prevent="deleBrand(index)">删除</a>
</td>
</tr>
<tr v-if="filteredBrands.length === 0">
<td colspan='4'>没有品牌数据</td>
</tr>
</table>
<table class='tb'>
:定义一个表格,类名为 tb,用于展示品牌信息。
<tr>
:定义表格的行,每一行表示一个品牌的信息。
v-for="(brand, index) in filteredBrands"
:Vue.js 的指令,用于循环渲染 filteredBrands 数组。每一行展示一个品牌的数据。
{{ index + 1 }}
:显示品牌的编号,从 1 开始。
{{ brand.brandName }}
:显示品牌的名称。
{{ brand.time }}
:显示品牌的创立时间。
<a href="#" class="delete-btn" @click.prevent="deleBrand(index)">删除</a>
:提供一个删除按钮,点击时触发 deleBrand 方法,删除对应品牌。
v-if="filteredBrands.length === 0"
:当 filteredBrands 数组为空时,显示 “没有品牌数据”。
Vue 实例部分
var brands = [
{ brandName: 'TCL', time: '2018-1-1' },
{ brandName: '小米', time: '2018-1-1' },
{ brandName: 'apple', time: '2018-1-1' }
];
brands 数组包含了初始的品牌数据,每个品牌对象有 brandName 和 time 两个属性,分别代表品牌名称和创立时间。
new Vue({
el: '#app',
data: {
brands: brands,
newBrandName: '',
searchQuery: ''
},
computed: {
filteredBrands() {
if (this.searchQuery) {
return this.brands.filter(brand =>
brand.brandName.toLowerCase().includes(this.searchQuery.toLowerCase())
);
}
return this.brands;
}
},
methods: {
addBrand() {
this.brands.unshift({
brandName: this.newBrandName,
time: new Date().toISOString().slice(0, 10)
});
this.newBrandName = '';
},
searchBrands() {
// 这里可以根据实际需求完善更复杂的搜索逻辑,目前简单依赖计算属性的筛选
},
deleBrand(index) {
if (confirm('确认删除吗?')) {
this.brands.splice(index, 1);
}
}
}
});
new Vue({ … }):创建一个新的 Vue 实例。
el: ‘#app’:将 Vue 实例挂载到 id 为 app 的 DOM 元素上。
data:存储 Vue 实例的响应式数据。包含 brands(品牌数据数组)、newBrandName(新增品牌名称)和 searchQuery(搜索框输入内容)。
computed:
filteredBrands:一个计算属性,用来过滤出符合搜索条件的品牌数据。如果 searchQuery 非空,则根据品牌名称进行大小写不敏感的搜索,否则返回全部品牌。
methods:定义了 Vue 实例中的方法。
addBrand:用来向 brands 数组中添加一个新的品牌,品牌的名称来自 newBrandName,创立时间是当前时间。
searchBrands:搜索方法,但当前实现是基于计算属性的。
deleBrand:删除指定索引位置的品牌,并通过 confirm 确认操作。
总结
本次实验让我深入学习和实践了 Vue.js 的核心概念,包括:
双向数据绑定 (v-model):学习了如何利用 Vue.js 实现输入框与数据之间的双向绑定,使得用户输入和数据实时同步。
动态渲染数据 (v-for):通过 v-for 指令学习如何根据数据渲染页面元素,特别是列表渲染和条件渲染。
事件绑定 (@click):学习了如何为 HTML 元素添加事件监听器,以响应用户的操作,如点击按钮时执行特定的 JavaScript 方法。
计算属性 (computed):通过计算属性处理了品牌列表的过滤问题,避免了在视图中直接操作数据。
Vue 实例的生命周期: 学习了 Vue.js 中的实例生命周期,如何管理和使用组件的生命周期钩子(如 mounted 和 destroyed)等。