搜索功能

1.搜索框组件:

 1 <template>
 2    <div class="search-list" >
 3           <el-input  v-model="query"  :placeholder="placeholder"></el-input>
 4           <span  v-show="query"   @click.prevent="clear" class="el-icon-error"></span>
 5    </div>
 6 </template>
 7 
 8 <script>
 9     export default {
10         name: "search-list",
11       props:{
12         placeholder:{
13           type:String,
14           default:'搜索歌曲、歌手'
15         }
16       },
17       data(){
18           return {
19             query:'',
20           }
21       },
22       methods:{
23         clear(){
24           console.log('qu')
25           this.query=''
26         },
27         setQuery(query){
28           console.log(query)
29           this.query = query
30         }
31       },
32       created(){
33           this.$watch('query',(newQuery)=>{//当搜索值发生变化的时候,将搜索值传递出去
34             this.$emit('query',newQuery )
35           })
36       }
37     }
38 </script>

2.搜索页面组件:

 1 <template>
 2     <div class="search">
 3       <search-list  ref="searchBox"   @query="onQueryChange"></search-list>
 4       <div class="hot-search">
 5         <div class="hot-title">热门搜索</div>
 6         <ul class="hot-list">
 7             <li    @click.stop.prevent="addQuery(item.k)"  class="host-span" v-for="(item) of  hotKey ">{{item.k}}</li>
 8         </ul>
 9       </div>
10       <div class="search-list-box">
11         <!--suggest需要传入query-->
12         <suggest  :query="query"></suggest>
13       </div>
14     </div>
15 </template>
16 
17 <script>
18   import SearchList from '@/base/search-list/search-list.vue'
19   import {getHotKey} from "../../api/search";
20   import {ERR_OK} from '@/api/config'
21   import Suggest from '@/components/suggest/suggest'
22 
23   export default {
24         name: "search",
25       components:{
26         SearchList,
27         Suggest,
28       },
29     data(){
30       return {
31         hotKey: [],
32         query: '',//是根据search-list里面的监听的query来变化的;所以在这里面监听search-list派发过来的query时间      }
33       }
34     },
35       created() {
36         this._getHotKey()
37       },
38       methods:{
39         onQueryChange(query){
40           this.query = query
41         },
42         _getHotKey() {
43           getHotKey().then((res) => {
44             if (res.code === ERR_OK) {
45               this.hotKey = res.data.hotkey.slice(0, 10)
46               console.log(this.hotKey)
47             }
48           })
49         },
50         addQuery(query){
51           this.$refs.searchBox.setQuery(query)
52         }
53       }
54 
55     }
56 </script>

3.搜索列表显示组件

 1 <template>
 2     <div class="suggest">
 3       <ul>
 4         <li  v-for="(item,index) of result">
 5           <div class="icon">
 6             <i :class="getIconCls"></i>
 7           </div>
 8           <div class="name">
 9             <p class="text"  v-html="getDisplayName(item)"></p>
10           </div>
11           </li>
12       </ul>
13     </div>
14 </template>
15 
16 <script>
17   import {search} from '@/api/search'
18   import {ERR_OK} from '@/api/config'
19   import {filterSinger} from '@/common/js/song'
20   const TYPE_SINGER = 'singer'//定义常量
21 
22   export default {
23         name: "suggest",
24       data(){
25         return {
26           result:[],
27           page:1,//第几页
28         }
29       },
30       props:{
31         query:{
32           type:String,
33           defauult:''
34         },
35         showSinger:{//是否显示歌手
36           type:Boolean,
37           default:true
38         }
39       },
40       watch:{
41           query(){//当搜素关键词发生变化时候调用search方法;
42             search(this.query,this.page,this.showSinger).then((res)=>{//song代表歌曲,zhida代表歌手信息;前面的icon不同;p代表页码数;catzhida:要不要检索歌手;
43                 if(res.code === ERR_OK){
44                   console.log(res)
45                   this.result = this._genResult(res)//得到的搜索列表
46                 }
47             })
48         }
49       },
50       methods:{
51           getIconCls(item){//显示图标
52              if(item.type === TYPE_SINGER){
53                 return 'icon-mine'
54              }else{
55                return "icon-music"
56              }
57           },
58           getDisplayName(item){//显示名字
59           if(item.type === TYPE_SINGER){
60             return item.singername
61           }else{
62             return `${item.songname} - ${filterSinger(item.singer)}`
63           }
64         },
65            _genResult(data) {
66           let ret = []
67           if (data.zhida && data.zhida.singerid) {//歌手push到返回值李
68             ret.push({...data.zhida, ...{type: TYPE_SINGER}})//用来区分后面列表显示是歌手;将两个添加到一个对象上
69           }
70           if (data.song) {
71             //ret =
72             ret = ret.concat(this._normalizeSongs(data.song.list))
73           }
74           return ret
75         },
76            _normalizeSongs(list) {
77           let ret = []
78           list.forEach((musicData) => {
79             if (musicData.songid && musicData.albummid) {
80               ret.push(createSong(musicData))
81             }
82           })
83           return ret
84         },
85       }
86     }
87 </script>

搜索逻辑:

1.suggest.vue是根据搜索关键词来从后台请求数据并展示数据,因此需要props搜索词query;

2.suggest.vue监听搜索词query,当query发生变化的时候发送search请求,并渲染列表

3.父组件search.vue将:query="query",把词传递过来。

4.搜索框search-list.vue监听query并派发query事件,并把query传递出去;

5.search.vue接听query事件,并将收到的query参数传递给suggest.vue。

posted @ 2018-08-14 10:00  前端极客  阅读(622)  评论(0编辑  收藏  举报