绝美宋词

发布时间 2023-06-04 15:24:02作者: GTK

习题链接

绝美宋词

课程列表

我有唐诗三百首,但是我想查找某一首诗,总不能一首一首查吧
所以我们要完成一个搜索功能模块,无论是诗句,还词牌,或者作者一并查出
并且要对查出来的数据进行高亮显示

关键点

  1. 在mounted生命周期中完成数据请求
    1. axios请求数据的
    2. axios中最常用的就是get与psot,axios是基于promise的异步操作,所以是可以是使用then,catch方法来处理结果的,在本题里面就是一个简单 请求
    3. axios.get(地址)
      .then(res=>{当请求成功,返回的结果在此处操作})
      .catch(err=>{执行失败的操作})
      .finally(()=>{成功或失败都将执行的操作})
  2. 正则表达式和eval的共同使用
    1. 在正则表达式的简写中想插入变量是不可能的,但是配合eval就可以了
    2. eval可以将字符串当成JS代码进行执行
    3. 一个句子里面可能存在多个匹配的字符所以用正则比较合适(本次解决方案使用的正则),再提供一种方案自己实现使用indexOf与while进行实现
  3. 使用replace方法
    1. 此方法不会修改原数组
    2. 匹配到的字符,可以使用$&字符进行实用,比如说你要匹配的"柳",再替换的字符串中使用$&就是对应的"柳"
  4. v-html指令,因为存在高亮标签,所以需要使用v-html对字符串进行html渲染
  5. watch使用监听器
    1. 因为每当查询条件发送变化的时候,需要触发一次查询
    2. 每次查询的结果基本上是不一致的所以不使用计算属性进行缓存

代码实现 && 完整的代码

  1. data中存在的数据
     data(){
         return {
           listdata:[],     // 所有的数据
           searchText:"",   // 查询字符串
           active:[]        // 查询结果
         }
     },
    
  2. 请求数据编写
    mounted(){
        axios.get("./data.json").then(res=> this.listdata = res.data )
    }
    
  3. 进行查询结果并拼接高亮标签
    watch:{
        searchText(){ 
          console.log(this.searchText);
          let arr = this.listdata.filter(item=>{
            let b = false;
            for (const key in item) { 
              let index = item[key].indexOf(this.searchText);
              if(index != -1){
                b = true; 
                item[key] = item[key].replace(eval(`/${this.searchText}/gi`),`<span class="highlight">$&</span>`)
              }
            } 
            return b;
          })
          // active是在data中进行声明的
          this.active = arr;
        }
    }, 
    
  4. 对查询结果进行渲染
     <div class="search-form">
       <input v-model="searchText" type="text" id="search" class="search" placeholder="词牌名 词句 词人"/>
       <ul class="suggestions">
         <li v-for="item,index in active">
           <span class="poet" v-html="item.poetry_content"></span>
           <span class="title"><span v-html="item.title"></span> - <span v-html="item.author"></span></span>
         </li>
       </ul> 
     </div>