目录😋
介绍
通常网站上会有搜索功能,方便用户定位搜索。本次试题我们要使用 Vue 2 的语法来完成一个关键字匹配的搜索功能。
准备
本题已经内置了初始代码,打开实验环境,目录结构如下:
├── css │ └── style.css ├── images ├── index.html └── vue.min.js
其中:
css/style.css是样式文件。images是项目所用到的图片文件。index.html是实现搜索功能的页面。vue.min.js是 Vue 文件。选中
index.html右键启动 Web Server 服务(Open with Live Server),让项目运行起来。 打开环境右侧的【Web 服务】,当前页面无法正常显示。
目标
请完善
index.html文件,让页面具有如下所示的效果:
规定
- 请严格按照考试步骤操作,切勿修改考试默认提供项目中的文件名称、文件夹路径等。
- 满足题目需求后,保持 Web 服务处于可以正常访问状态,点击「提交检测」系统会自动判分。
通关代码✔️
//index.html <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <script src="vue.min.js"></script> <link rel="stylesheet" href="./css/style.css" /> </head> <body> <div id="app"> <div class="search-wrapper"> <input type="text" v-model="search" placeholder="请搜索" /> </div> <div class="wrapper"> <div class="card" v-for="post in filteredList"> <a v-bind:href="post.link" target="_blank"> <img v-bind:src="post.img" /> {{ post.title }} </a> </div> </div> </div> <script> class Post { constructor(title, link, img) { this.title = title; this.link = link; this.img = img; } } const app = new Vue({ el: "#app", data: { search: "", postList: [ new Post( "小猫咪", "https://unsplash.com/s/photos/cat", "./images/cat.png" ), new Post( "小狗狗", "https://unsplash.com/@joeyc", "./images/dog.png" ), new Post( "北极熊", "https://unsplash.com/@hansjurgen007", "./images/bar.png" ), new Post( "狮子", "https://unsplash.com/@hansjurgen007", "./images/lion.png" ), new Post( "小鸟", "https://unsplash.com/@eugenechystiakov", "./images/birds.png" ), new Post( "狐狸", "https://unsplash.com/@introspectivedsgn", "./images/fox.png" ), ], }, computed: { filteredList() { // TODO: 请补充代码 if(this.search === ''){ return this.postList; }else{ return this.postList.filter(post=>{ return post.title.toLowerCase().includes(this.search.toLowerCase()); }) } }, }, }); </script> </body> </html>
代码解析📑
1. HTML 部分
<html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <script src="vue.min.js"></script> <link rel="stylesheet" href="./css/style.css" /> </head> <body> <div id="app"> <div class="search-wrapper"> <input type="text" v-model="search" placeholder="请搜索" /> </div> <div class="wrapper"> <div class="card" v-for="post in filteredList"> <a v-bind:href="post.link" target="_blank"> <img v-bind:src="post.img" /> {{ post.title }} </a> </div> </div> </div> <script> // JavaScript 代码部分 </script> </body> </html>
解释:
<input type="text" v-model="search" placeholder="请搜索">:
v-model="search":使用 Vue 的v-model指令将输入框的值与 Vue 实例中的search数据属性进行双向绑定。这意味着当用户在输入框中输入文本时,输入的内容会自动更新search的值,反之亦然。
2. JavaScript 部分
class Post { constructor(title, link, img) { this.title = title; this.link = link; this.img = img; } } const app = new Vue({ el: "#app", data: { search: "", postList: [ new Post( "小猫咪", "https://unsplash.com/s/photos/cat", "./images/cat.png" ), new Post( "小狗狗", "https://unsplash.com/@joeyc", "./images/dog.png" ), new Post( "北极熊", "https://unsplash.com/@hansjurgen007", "./images/bar.png" ), new Post( "狮子", "https://unsplash.com/@hansjurgen007", "./images/lion.png" ), new Post( "小鸟", "https://unsplash.com/@eugenechystiakov", "./images/birds.png" ), new Post( "狐狸", "https://unsplash.com/@introspectivedsgn", "./images/fox.png" ), ], }, computed: { filteredList() { if(this.search === ''){ return this.postList; }else{ return this.postList.filter(post=>{ return post.title.toLowerCase().includes(this.search.toLowerCase()); }) } }, }, });
解释:
class Post:
- 定义了一个
Post类,用于存储每个帖子的信息,包括title、link和img。
const app = new Vue({...}):创建一个 Vue 实例。
data:
search:存储用户在输入框中输入的搜索关键字。postList:存储一个Post对象的数组,每个Post对象包含一个帖子的信息。
computed:
filteredList():一个计算属性,用于根据用户输入的关键字筛选postList中的元素。
if(this.search === ''):检查search属性是否为空。
- 如果
search为空,说明用户没有输入任何搜索关键字,直接返回整个postList,显示所有帖子。
else:如果search不为空,使用filter方法对postList进行过滤。
this.postList.filter(post=>{...}):
post => {...}是filter方法的回调函数,会对postList中的每个post对象进行操作。post.title.toLowerCase().includes(this.search.toLowerCase()):
post.title.toLowerCase():将当前post对象的title属性转换为小写,确保搜索不区分大小写。this.search.toLowerCase():将用户输入的搜索关键字转换为小写。includes():检查post的title是否包含用户输入的关键字。- 如果包含,
includes()方法返回true,该post对象会被添- 加到新数组中;否则,返回
false,该post对象会被排除。3. 工作流程▶️
- 用户在输入框中输入关键字。
- 输入的关键字通过
v-model绑定到 Vue 实例的search属性。- Vue 的响应式系统会检测到
search属性的变化。- 由于
filteredList是一个计算属性,它会重新计算。- 在
filteredList的计算逻辑中:
- 如果
search为空,返回完整的postList数组。- 若
search不为空,使用filter方法遍历postList数组,对每个post对象检查其title是否包含输入的关键字(不区分大小写),将符合条件的post对象添加到一个新数组中。
- 最终,
v-for="post in filteredList"会根据filteredList计算属性的结果更新页面显示,只显示符合搜索关键字的帖子。4. 小总结😎
通过 Vue 的数据绑定(
v-model)、计算属性(computed)和数组的filter方法,实现了一个简单但有效的关键字匹配搜索功能。用户输入的关键字会触发 Vue 实例中数据的更新,进而触发计算属性的重新计算,最终更新页面上显示的帖子列表,仅显示那些标题中包含用户输入关键字的帖子。这展示了 Vue 数据驱动视图的特性,让数据的更新自动反映在页面上,减少了手动操作 DOM 的繁琐,提高了开发效率。
测试结果👍