基于Vue.js實(shí)現(xiàn)簡(jiǎn)單搜索框
在github上看到的練習(xí),看個(gè)遍代碼后自己再練一遍,先放原址:https://github.com/lavyun/vue-demo-search
主要用到的知識(shí)很簡(jiǎn)單,簡(jiǎn)單的vuejs2.0的知識(shí)就夠了。源碼用了.vue構(gòu)建和ES6,用了webpack打包等等。我資歷還淺,先用一個(gè)簡(jiǎn)單的.js的寫。
先看效果

這里有兩個(gè)組件,一個(gè)組件是logo部分的,一個(gè)是搜索框部分的。
html
html很簡(jiǎn)單,就是引用兩個(gè)組件。
<div id="app">
<logo-picture></logo-picture>
<search-panel></search-panel>
</div>
//js還要實(shí)例#app
var app = new Vue({
el: "#app"
})
logo
先來分析,首先一個(gè)<img />顯示搜索引擎的圖片,這里要響應(yīng)式的,下面選擇了不同的搜索引擎圖標(biāo)就要跟著換。所以<img :src="items[now].src" />。后面的倒三角點(diǎn)擊時(shí)顯示下拉列表<span @click="toggleFlag"> </span>。
然后是下拉框。如果想要有過渡效果,那個(gè)就要包裹在<transition-group中,然后遍歷li,記住元素要指定唯一的key。
想要有hover效果的話,用數(shù)據(jù)驅(qū)動(dòng)的思維,就是比較index 與hoverindex是否相等,如果相等就加class。
Vue.component('logo-picture',{
template :' \
<div class="main-logo">\
<img :src="items[now].src" @click="toggleFlag"/>\
<span @click="toggleFlag" class="logoList-arrow"> </span>\
<transition-group tag="ul" v-show="flagShow" class="logoList">\
<li v-for="(item,index) in items" :key="index" @click="changeFlag(index)" @mouseover="flagHover(index)" :class="{selectback: index == hoverindex}">\
<img :src="item.src" />\
</li>\
</transition>\
</div>',
data: function() {
return {
items: [{src:'../src/assets/360_logo.png'},{src:'../src/assets/baidu_logo.png'},{src:'../src/assets/sougou_logo.png'}],
now: 0,
flagShow: false,
hoverindex: -1
}
},
methods: {
//顯示隱藏圖片列表
toggleFlag: function() {
this.flagShow = !this.flagShow;
},
//改變搜索引擎
changeFlag: function(index) {
this.now = index;
this.flagShow = false;
bus.$emit("change",index);
},
//li hover
flagHover: function(index) {
this.hoverindex = index;
}
}
});
下拉框
input因?yàn)橐p向綁定,所以要v-model="keyword",還要綁定鍵盤事件@keyup,如果按enter就搜索,向下向上就選中給定的返回信息列表。
下面的詳情框與<logo-picture>下拉列表差不多。
搜索的話主要是運(yùn)用$http.jsonp,還有ES6的語(yǔ)法?回掉好像是Promise的.then()。
Vue.component('search-panel',{
template:'\
<div class="search-input">\
<input v-model="search" @keyup="get($event)" @keydown.enter="searchInput()" @keydown.down="selectDown()" @keydown.up.prevent="selectUp()"/>\
<span @click="clearInput()" class="search-reset">×</span>\
<button @click="searchInput()" class="search-btn">搜一下</button>\
<div class="search-select">\
<transition-group tag="ul" mode="out-in">\
<li v-for="(value,index) in myData" :class="{selectback:index==now}" :key="index" @click="searchThis" @mouseover="selectHover(index)" class="search-select-option search-select-list">\
{{value}}\
</li>\
</transition-group>\
</div>\
</div>',
data: function() {
return {
search: '',
myData: [],
flag: 0,
now: -1,
logoData: [
{
'name': "360搜索",
searchSrc: "https://www.so.com/s?ie=utf-8&shb=1&src=360sou_newhome&q="
},
{
'name': "百度搜索",
searchSrc: "https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=0&rsv_idx=1&tn=baidu&wd="
},
{
'name': "搜狗搜索",
searchSrc: "https://www.sogou.com/web?query="
}
]
}
},
methods: {
get: function(event) {
if(event.keyCode == 38 || event.keyCode == 40){ //向上向下
return ;
}
this.$http.jsonp('https://sug.so.#/suggest?word=' + this.search + '&encodein=utf-8&encodeout=utf-8').then(function(res) {
this.myData = res.data.s;
}, function() {
});
},
//清除內(nèi)容
clearInput: function() {
this.search = '';
this.get();
},
//搜索
searchInput: function() {
alert(this.flag)
window.open(this.logoData[this.flag].searchSrc+this.search);
},
//搜索的內(nèi)容
searchThis: function(index) {
this.search = this.myData[index];
this.searchInput();
},
//li hover
selectHover: function(index) {
this.search = this.myData[index];
this.now = index;
},
//向下
selectDown: function() {
this.now++;
if(this.now == this.myData.length) {
this.now = 0;
}
this.search = this.myData[this.now];
},
//向上
selectUp: function() {
this.now--;
if(this.now == -1) {
this.now = this.myData.length - 1;
}
this.search = this.myData[this.now];
}
},
created: function() { //通信
var self = this;
bus.$on('change',function(index) {
self.flag = index;
})
}
})
兩個(gè)兄弟組件通信的問題
<logo-picture>換了搜索引擎的話,<search-panel>要換成相應(yīng)的搜索引擎。這里要新建一個(gè)空的Vue對(duì)象做中間,因?yàn)閮蓚€(gè)組件不是父子關(guān)系。
var bus = new Vue();
//logo-picture里觸發(fā)事件,并傳遞參數(shù)
bus.$emit("change",index);
//search-panel里監(jiān)聽事件是否發(fā)生
var self = this;
bus.$on('change',function(index) {
self.flag = index;
})
這里要注意this問題,$on里this指向bus,所以要保存this才能引用search-panel.
本文已被整理到了《Vue.js前端組件學(xué)習(xí)教程》,歡迎大家學(xué)習(xí)閱讀。
關(guān)于vue.js組件的教程,請(qǐng)大家點(diǎn)擊專題vue.js組件學(xué)習(xí)教程進(jìn)行學(xué)習(xí)。
更多搜索功能實(shí)現(xiàn)的精彩文章,請(qǐng)點(diǎn)擊專題:javascript搜索功能匯總 進(jìn)行學(xué)習(xí)
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Vue3+Element-Plus實(shí)現(xiàn)左側(cè)菜單折疊與展開功能示例
關(guān)于el-table-column的formatter的使用及說明
詳解vue-router的導(dǎo)航鉤子(導(dǎo)航守衛(wèi))
vue基于Teleport實(shí)現(xiàn)Modal組件
詳解vue與后端數(shù)據(jù)交互(ajax):vue-resource
vue element upload組件 file-list的動(dòng)態(tài)綁定實(shí)現(xiàn)

