绝美宋词
介绍
“今宵酒醒何处,杨柳岸晓风残月”,“蓦然回首,那人却在灯火阑珊处”,“试问闲愁都几许?一川烟草,满城风絮,梅子黄时雨” ……
宋词可谓是古代文学桂冠上一颗璀璨的明珠,本题将实现一个在搜索框中输入关键字,实时显示符合条件的完整宋词的功能。
准备
本题已经内置了初始代码,打开实验环境,目录结构如下:
1 2 3 4 5 6 7
| ├── 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 结构按照如下规定显示:
1 2 3 4 5
| <li> <span class="poet">词句</span> <span class="title">词牌名 - 词人</span> </li>
|
例:
1 2 3 4 5 6
| <li> <span class="poet" >常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭</span > <span class="title">如梦令 - 李清照</span> </li>
|
- 高亮匹配到的所有词句中的关键词。即使用
<span class="highlight"></span> 标签包裹所有关键词。
例:(关键词:雨)
1 2 3 4 5 6 7
| <li> <span class="poet" >寒蝉凄切,对长亭晚,骤<span class="highlight">雨</span >初歇。都门帐饮无绪,方留恋处,兰舟催发。执手相看泪眼,竟无语凝噎。念去去千里烟波,暮霭沉沉楚天阔。多情自古伤离别,更那堪冷落清秋节。今宵酒醒何处,杨柳岸晓风残月。此去经年,应是良辰美景虚设。便纵有千种风情,更与何人说</span > <span class="title"><span class="highlight">雨</span>霖铃 - 柳永</span> </li>
|
注意:本题要求的是实时显示,即输入完成的同时显示结果,非失去焦点显示。
完成后,最终页面效果如下:

规定
- 请勿修改已经提供的代码,以免造成判题无法通过。
- 请严格按照考试步骤操作,切勿修改考试默认提供项目中的文件名称、文件夹路径等。
- 满足题目需求后,保持 Web 服务处于可以正常访问状态,点击「提交检测」系统会自动判分
判分标准
总通过次数: 933 | 总提交次数: 1053 | 通过率: 88.6%
难度: 中等 标签: 2022, 省模拟赛, Web 前端, Vue.js
题解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| <!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="searchQuery" /> <ul class="suggestions"> <!-- 每一首完整词句用一个 li 包裹 --> <li v-for="item in showList" :key="item.poetry_content"> <span class="poet" v-html="item.poetry_content"></span> <span class="title" v-html="`${item.title} - ${item.author}`"></span> </li> </ul> </div> </div> <script> let vm = new Vue({ el: "#app", // TODO:待补充代码 data() { return { dataList: [], searchQuery: "", }; }, computed: { showList() { const result = [] const hashMap = {} if (this.searchQuery.trim() === '') { return result } // 清除所有先前插入的span标签 const dataListCopy = this.dataList.map(item => ({ ...item })); dataListCopy.forEach(item => { for(let key in item) { const reg = new RegExp(this.searchQuery) if (reg.test(item[key])) { // handle item[key] = item[key].replaceAll(this.searchQuery, `<span class="highlight">${this.searchQuery}</span>`) // push result.push(item) } } }) // de delipicate for(let i = 0; i < result.length - 1; i++) { if (result[i].poetry_content === result[i+1].poetry_content) { result.splice(i, 1) } } return result }, }, mounted() { fetch("./data.json", { method: "get" }) .then((res) => res.json()) .then((data) => { this.dataList = data; }); }, }); </script> </body> </html>
|