介绍
"今宵酒醒何处,杨柳岸晓风残月","蓦然回首,那人却在灯火阑珊处","试问闲愁都几许?一川烟草,满城风絮,梅子黄时雨" ......
宋词可谓是古代文学桂冠上一颗璀璨的明珠,本题将实现一个在搜索框中输入关键字,实时显示符合条件的完整宋词的功能。
准备
本题已经内置了初始代码,打开实验环境,目录结构如下:
├── css
│ └── style.css
├── data.json
├── index.html
└── js
├── axios.min.js
└── vue.min.js
其中:
index.html
是主页面。js/vue.min.js
是项目用到的 vue2.x 版本文件。js/axios.min.js
是 axios 文件。data.json
是项目中需要用到宋词数据。css/style.css
是样式文件。
选中 index.html
右键启动 Web Server 服务(Open with Live Server),让项目运行起来。
接着,打开环境右侧的【Web 服务】,就可以在浏览器中看到如下效果:

目标
请使用 Vue ,完成 index.html
文件中的 TODO 部分。
-
完成数据请求(数据来源
./data.json
),data.json
是宋词数据,poetry_content
表示词句,title
表示词牌名,author
表示词人。 -
在输入框输入关键词时在
ul
(class = suggestions
)的元素中实时显示 词牌名、词句、词人中包含关键词的完整词句(包含词牌名、词人)列表 ,当关键词为空或者匹配不到时ul
(class = suggestions
)元素的子节点为空。完整词句的 DOM 结构按照如下规定显示: - 词句 词牌名 - 词人
例:
<li>
<span class="poet"
>常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭</span
>
<span class="title">如梦令 - 李清照</span>
</li>
- 高亮匹配到的所有词句中的关键词。即使用
<span class="highlight"></span>
标签包裹所有关键词。
例:(关键词:雨)
<li>
<span class="poet"
>寒蝉凄切,对长亭晚,骤<span class="highlight">雨</span
>初歇。都门帐饮无绪,方留恋处,兰舟催发。执手相看泪眼,竟无语凝噎。念去去千里烟波,暮霭沉沉楚天阔。多情自古伤离别,更那堪冷落清秋节。今宵酒醒何处,杨柳岸晓风残月。此去经年,应是良辰美景虚设。便纵有千种风情,更与何人说</span
>
<span class="title"><span class="highlight">雨</span>霖铃 - 柳永</span>
</li>
注意 :本题要求的是实时显示,即输入完成的同时显示结果,非失去焦点显示。
规定
- 请勿修改已经提供的代码,以免造成判题无法通过。
- 请严格按照考试步骤操作,切勿修改考试默认提供项目中的文件名称、文件夹路径等。
- 满足题目需求后,保持 Web 服务处于可以正常访问状态,点击「提交检测」系统会自动判分
代码
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>绝美宋词</title>
<link rel="stylesheet" href="css/style.css" />
<script src="./js/vue.min.js"></script>
<script src="./js/axios.min.js"></script>
</head>
<body>
<div id="app">
<h1 style="text-align: center">输入关键字,找一首词</h1>
<!-- TODO:待补充代码 -->
<div class="search-form">
<input
type="text"
id="search"
class="search"
placeholder="词牌名 词句 词人"
v-model="searchValue"
/>
<ul class="suggestions" v-for="item in setSearchData">
<!-- 每一首完整词句用一个 li 包裹 -->
<li>
<span class="poet" v-html="highlight(item.poetry_content)"
>{{item.poetry_content}}</span
>
<span class="title">
<span v-html="highlight(item.title)">{{item.title}}</span>
-
<span v-html="highlight(item.author)">{{item.author}}</span>
</span>
</li>
</ul>
</div>
</div>
<script>
let vm = new Vue({
el: "#app",
// TODO:待补充代码
data: {
dataList: [],
searchValue: "",
},
mounted() {
axios.get("./data.json").then((res) => {
this.dataList = res.data;
console.log(res.data);
});
},
computed: {
setSearchData() {
// 当搜索值为空时返回空数组
if (!this.searchValue) return [];
// 正确过滤包含搜索词的项
return this.dataList.filter((item) => {
return (
item.poetry_content.includes(this.searchValue) ||
item.title.includes(this.searchValue) ||
item.author.includes(this.searchValue)
);
});
},
},
methods: {
highlight(it) {
// 替换搜索词并高亮显示
return it.replaceAll(
this.searchValue,
`<span class="highlight">$&</span>`
);
},
},
});
</script>
</body>
</html>
v-html="highlight(...)
:使用v-html
指令渲染 HTML 内容,highlight
方法会将匹配搜索词的部分用<span class="highlight">
包裹,实现高亮效果。
javascript
computed: {
setSearchData() {
if (!this.searchValue) return [];
return this.dataList.filter((item) => {
return (
item.poetry_content.includes(this.searchValue) ||
item.title.includes(this.searchValue) ||
item.author.includes(this.searchValue)
);
});
},
},
- 作用 :根据
searchValue
的值动态过滤dataList
,返回包含搜索词的诗词数据。 - 工作原理 :
- 当
searchValue
为空时,返回空数组,隐藏所有结果。 - 当
searchValue
有值时,使用filter
方法遍历dataList
,筛选出poetry_content
(诗词内容)、title
(词牌名)或author
(词人)包含搜索词的项。
- 当
- 响应式 :计算属性会自动追踪依赖的响应式数据(
searchValue
和dataList
),当它们变化时,重新计算并更新视图。
javascript
methods: {
highlight(it) {
return it.replaceAll(this.searchValue, `<span class="highlight">$&</span>`);
},
},
highlight
方法 :- 接收一个字符串
it
(如诗词内容、词牌名或词人)。 - 使用
replaceAll
方法将it
中所有匹配searchValue
的部分替换为<span class="highlight">$&</span>
,其中$&
表示匹配的子字符串。 - 最终返回带有高亮样式的 HTML 字符串,通过
v-html
渲染到页面上,实现搜索词高亮效果。
- 接收一个字符串