前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【Vue.js——关键字搜索】绝美宋词(蓝桥杯真题-2327)【合集】

【Vue.js——关键字搜索】绝美宋词(蓝桥杯真题-2327)【合集】

作者头像
Rossy Yan
发布2025-02-02 21:30:49
发布2025-02-02 21:30:49
4200
代码可运行
举报
运行总次数:0
代码可运行

背景介绍

“今宵酒醒何处,杨柳岸晓风残月”,“蓦然回首,那人却在灯火阑珊处”,“试问闲愁都几许?一川烟草,满城风絮,梅子黄时雨” ...... 宋词可谓是古代文学桂冠上一颗璀璨的明珠,本题将实现一个在搜索框中输入关键字,实时显示符合条件的完整宋词的功能。

准备步骤

本题已经内置了初始代码,打开实验环境,目录结构如下:

代码语言:javascript
代码运行次数:0
运行
复制
├── 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 部分。

1. 完成数据请求(数据来源 ./data.json),data.json 是宋词数据,poetry_content 表示词句,title 表示词牌名,author 表示词人。

2. 在输入框输入关键词时在 ulclass = suggestions)的元素中实时显示词牌名、词句、词人中包含关键词的完整词句(包含词牌名、词人)列表,当关键词为空或者匹配不到时 ulclass = suggestions)元素的子节点为空。完整词句的 DOM 结构按照如下规定显示:

代码语言:javascript
代码运行次数:0
运行
复制
<!-- 每一首完整词句用一个 li 包裹 -->
<li>
  <span class="poet">词句</span>
  <span class="title">词牌名 - 词人</span>
</li>

例:

代码语言:javascript
代码运行次数:0
运行
复制
<li>
  <span class="poet"
    >常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭</span
  >
  <span class="title">如梦令 - 李清照</span>
</li>

3. 高亮匹配到的所有词句中的关键词。即使用 <span class="highlight"></span> 标签包裹所有关键词。

例:(关键词:雨)

代码语言:javascript
代码运行次数:0
运行
复制
<li>
  <span class="poet"
    >寒蝉凄切,对长亭晚,骤<span class="highlight">雨</span
    >初歇。都门帐饮无绪,方留恋处,兰舟催发。执手相看泪眼,竟无语凝噎。念去去千里烟波,暮霭沉沉楚天阔。多情自古伤离别,更那堪冷落清秋节。今宵酒醒何处,杨柳岸晓风残月。此去经年,应是良辰美景虚设。便纵有千种风情,更与何人说</span
  >
  <span class="title"><span class="highlight">雨</span>霖铃 - 柳永</span>
</li>

注意本题要求的是实时显示,即输入完成的同时显示结果,非失去焦点显示

完成后,最终页面效果如下:


要求规定

  • 请勿修改已经提供的代码,以免造成判题无法通过。
  • 请严格按照考试步骤操作,切勿修改考试默认提供项目中的文件名称、文件夹路径等。
  • 满足题目需求后,保持 Web 服务处于可以正常访问状态,点击「提交检测」系统会自动判分

判分标准

  • 本题完全实现题目目标得满分,否则得 0 分。

通关代码✔️

代码语言:javascript
代码运行次数:0
运行
复制
<!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>
    <!-- 绑定输入框的输入事件 -->
    <div class="search-form">
      <input type="text" id="search" class="search" placeholder="词牌名 词句 词人" v-model="keyword" @input="filterPoetry"/>
      <ul class="suggestions">
        <!-- 循环渲染符合条件的词句 -->
        <li v-for="poetry in filteredPoetry" :key="poetry.id">
          <span class="poet" v-html="highlightKeyword(poetry.poetry_content, keyword)"></span>
          <span class="title" v-html="highlightKeyword(poetry.title + ' - ' + poetry.author, keyword)"></span>
        </li>
      </ul>
    </div>
  </div>
  <script>
    let vm = new Vue({
      el: '#app',
      data: {
        keyword: '', // 输入的关键词
        poetryList: [], // 存储从 data.json 获取的所有宋词数据
        filteredPoetry: [] // 存储过滤后的符合条件的宋词数据
      },
      mounted() {
        // 组件挂载后请求数据
        this.fetchPoetryData();
      },
      methods: {
        fetchPoetryData() {
          // 使用 axios 请求 data.json 文件
          axios.get('./data.json')
            .then(response => {
              this.poetryList = response.data;
            })
            .catch(error => {
              console.error('数据请求失败:', error);
            });
        },
        filterPoetry() {
          if (this.keyword === '') {
            this.filteredPoetry = [];
          } else {
            this.filteredPoetry = this.poetryList.filter(poetry => {
              // 检查词牌名、词句、词人中是否包含关键词
              return poetry.poetry_content.includes(this.keyword) || poetry.title.includes(this.keyword) || poetry.author.includes(this.keyword);
            });
          }
        },
        highlightKeyword(text, keyword) {
          if (!keyword) return text;
          // 使用正则表达式替换关键词,并用 <span class="highlight"></span> 包裹
          const regex = new RegExp(keyword, 'gi');
          return text.replace(regex, '<span class="highlight">$&</span>');
        }
      }
    });
  </script>
</body>

</html>

代码解析📑

一、Html 部分

代码语言:javascript
代码运行次数:0
运行
复制
<!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>
    <!-- 绑定输入框的输入事件 -->
    <div class="search-form">
      <input type="text" id="search" class="search" placeholder="词牌名 词句 词人" v-model="keyword" @input="filterPoetry"/>
      <ul class="suggestions">
        <!-- 循环渲染符合条件的词句 -->
        <li v-for="poetry in filteredPoetry" :key="poetry.id">
          <span class="poet" v-html="highlightKeyword(poetry.poetry_content, keyword)"></span>
          <span class="title" v-html="highlightKeyword(poetry.title + ' - ' + poetry.author, keyword)"></span>
        </li>
      </ul>
    </div>
  </div>
  <script>
    let vm = new Vue({
      el: '#app',
      data: {
        keyword: '', // 输入的关键词
        poetryList: [], // 存储从 data.json 获取的所有宋词数据
        filteredPoetry: [] // 存储过滤后的符合条件的宋词数据
      },
      mounted() {
        // 组件挂载后请求数据
        this.fetchPoetryData();
      },
      methods: {
        fetchPoetryData() {
          // 使用 axios 请求 data.json 文件
          axios.get('./data.json')
            .then(response => {
              this.poetryList = response.data;
            })
            .catch(error => {
              console.error('数据请求失败:', error);
            });
        },
        filterPoetry() {
          if (this.keyword === '') {
            this.filteredPoetry = [];
          } else {
            this.filteredPoetry = this.poetryList.filter(poetry => {
              // 检查词牌名、词句、词人中是否包含关键词
              return poetry.poetry_content.includes(this.keyword) || poetry.title.includes(this.keyword) || poetry.author.includes(this.keyword);
            });
          }
        },
        highlightKeyword(text, keyword) {
          if (!keyword) return text;
          // 使用正则表达式替换关键词,并用 <span class="highlight"></span> 包裹
          const regex = new RegExp(keyword, 'gi');
          return text.replace(regex, '<span class="highlight">$&</span>');
        }
      }
    });
  </script>
</body>

</html>
  1. <head> 部分
    • meta charset="UTF-8":设置文档的字符编码为 UTF - 8。
    • <title>:设置页面标题为 “绝美宋词”。
    • <link>:引入外部 CSS 文件 css/style.css,用于页面样式。
    • <script>:引入 Vue.js 和 Axios 库,分别用于构建交互式界面和发送 HTTP 请求。
  2. <body> 部分
    • <div id="app">:Vue 实例的挂载点。
    • <h1>:显示标题 “输入关键字,找一首词”。
    • <input>:输入框,使用 v-model 指令绑定 keyword 数据属性,实现双向数据绑定;使用 @input 指令监听输入事件,调用 filterPoetry 方法进行数据过滤。
    • <ul>:用于显示符合条件的宋词列表,使用 v-for 指令循环渲染 filteredPoetry 数组中的元素。
    • <span>:分别显示词句和词牌名 - 词人信息,使用 v-html 指令插入经过高亮处理的 HTML 内容。
  3. <script> 部分
    • 创建 Vue 实例,挂载到 #app 元素上。
    • data:定义三个数据属性:keyword 用于存储用户输入的关键词,poetryList 用于存储从 data.json 获取的所有宋词数据,filteredPoetry 用于存储过滤后的符合条件的宋词数据。
    • mounted:组件挂载后调用 fetchPoetryData 方法,发送 GET 请求获取 data.json 文件中的数据。
    • methods
      • fetchPoetryData:使用 Axios 发送 GET 请求,将响应数据存储在 poetryList 中。
      • filterPoetry:根据 keyword 过滤 poetryList 中的数据,将符合条件的宋词数据存储在 filteredPoetry 中。
      • highlightKeyword:使用正则表达式替换文本中的关键词,并用 <span class="highlight"></span> 包裹,实现关键词高亮显示。

二、CSS 部分

代码语言:javascript
代码运行次数:0
运行
复制
html {
  box-sizing: border-box;
  background: hsl(145deg 30% 63%);
  font-family: "Kaiti", "SimHei", "Hiragino Sans GB ", "helvetica neue";
  font-size: 20px;
  font-weight: 200;
}
*,
*:before,
*:after {
  box-sizing: inherit;
}
input {
  width: 100%;
  padding: 20px;
  font-family: "Kaiti", "helvetica neue";
}
.search-form {
  max-width: 700px;
  margin: 50px auto;
}

input.search {
  margin: 0;
  text-align: center;
  outline: 0;
  border: 10px solid #f7f7f7;
  width: 120%;
  left: -10%;
  position: relative;
  top: 10px;
  z-index: 2;
  border-radius: 5px;
  font-size: 40px;
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.12), inset 0 0 2px rgba(0, 0, 0, 0.19);
}

.suggestions {
  margin: 0;
  padding: 0;
  position: relative;
  /*perspective:20px;*/
}
.suggestions li {
  background: white;
  list-style: none;
  border-bottom: 1px solid #d8d8d8;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.14);
  margin: 0;
  padding: 20px;
  transition: background 0.2s;
  display: flex;
  justify-content: center;
}

.suggestions li:nth-child(even) {
  transform: perspective(100px) rotateX(3deg) translateY(2px) scale(1.001);
  background: linear-gradient(to bottom, #ffffff 0%, #efefef 100%);
}
.suggestions li:nth-child(odd) {
  transform: perspective(100px) rotateX(-3deg) translateY(3px);
  background: linear-gradient(to top, #ffffff 0%, #efefef 100%);
}
span.population {
  font-size: 15px;
}

span.info {
  display: flex;
  flex-direction: column;
}
span.author,
span.title {
  font-size: 0.8em;
  /*		right: 0;*/
}
span.title {
  color: #7c8e94;
  position: absolute;
  right: 5px;
  bottom: 1px;
}

.details {
  text-align: center;
  font-size: 15px;
}

.highlight {
  color: #ff0000;
}

.love {
  text-align: center;
}

a {
  color: black;
  background: rgba(0, 0, 0, 0.1);
  text-decoration: none;
}
  1. 全局样式
    • html:设置页面的背景颜色、字体家族、字体大小和字体粗细。
    • *, *:before, *:after:使用 box-sizing: inherit 继承 html 元素的盒模型设置。
  2. 输入框样式
    • input:设置输入框的宽度、内边距和字体家族。
    • .search-form:设置搜索表单的最大宽度和外边距。
    • input.search:设置输入框的样式,包括边框、宽度、位置、字体大小和阴影等。
  3. 搜索结果列表样式
    • .suggestions:设置搜索结果列表的外边距和内边距。
    • .suggestions li:设置列表项的背景颜色、边框、阴影和内边距等。
    • .suggestions li:nth-child(even).suggestions li:nth-child(odd):为偶数和奇数列表项设置不同的背景渐变和 3D 效果。
  4. 其他样式
    • span.populationspan.infospan.authorspan.title:设置不同元素的字体大小和颜色。
    • .highlight:设置高亮关键词的颜色为红色。

三、JSON 部分

代码语言:javascript
代码运行次数:0
运行
复制
[
  {
    "poetry_content": "寒蝉凄切,对长亭晚,骤雨初歇。都门帐饮无绪,方留恋处,兰舟催发。执手相看泪眼,竟无语凝噎。念去去千里烟波,暮霭沉沉楚天阔。多情自古伤离别,更那堪冷落清秋节。今宵酒醒何处,杨柳岸晓风残月。此去经年,应是良辰美景虚设。便纵有千种风情,更与何人说",
    "title": "雨霖铃",
    "author": "柳永"
  },
  // 其他宋词数据...
]

这是一个包含多个宋词对象的数组,每个宋词对象包含三个属性:

  • poetry_content:存储宋词的具体词句。
  • title:存储词牌名。
  • author:存储词人姓名。

四、工作流程 ▶️

  1. 页面加载
    • 浏览器加载 HTML 文件,引入 CSS 和 JavaScript 资源。
    • Vue 实例挂载到 #app 元素上,在 mounted 钩子函数中调用 fetchPoetryData 方法。
    • fetchPoetryData 方法使用 Axios 发送 GET 请求,从 data.json 文件中获取宋词数据,并将数据存储在 poetryList 中。
  2. 用户输入关键词
    • 用户在输入框中输入关键词,v-model 指令将输入的值绑定到 keyword 数据属性上。
    • 输入框触发 @input 事件,调用 filterPoetry 方法。
  3. 数据过滤
    • filterPoetry 方法根据 keyword 过滤 poetryList 中的数据,将词牌名、词句、词人中包含关键词的宋词数据存储在 filteredPoetry 中。
    • 如果 keyword 为空,则将 filteredPoetry 清空。
  4. 结果渲染
    • 使用 v-for 指令循环渲染 filteredPoetry 数组中的元素,将每一首符合条件的宋词显示在 <ul> 元素中。
    • 在渲染过程中,调用 highlightKeyword 方法对词句和词牌名 - 词人信息进行高亮处理,将匹配到的关键词用 <span class="highlight"></span> 包裹。
  5. 样式展示
    • CSS 文件为页面元素提供样式,包括输入框、搜索结果列表、高亮关键词等,使页面呈现出美观的效果。

测试结果👍

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-01-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景介绍
  • 准备步骤
  • 目标效果
  • 要求规定
  • 判分标准
  • 通关代码✔️
  • 代码解析📑
    • 一、Html 部分
    • 二、CSS 部分
    • 三、JSON 部分
  • 测试结果👍
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档