在github上看到的练习,看个遍代码后自己再练一遍,先放原址:https://github.com/lavyun/vue-demo-search
主要用到的知识很简单,简单的vuejs2.0的知识就够了。源码用了.vue构建和ES6,用了webpack打包等等。我资历还浅,先用一个简单的.js的写。
先看效果
这里有两个组件,一个组件是logo部分的,一个是搜索框部分的。
html很简单,就是引用两个组件。
<div id="app">
<logo-picture></logo-picture>
<search-panel></search-panel>
</div>
//js还要实例#app
var app = new Vue({
el: "#app"
})
先来分析,首先一个显示搜索引擎的图片,这里要响应式的,下面选择了不同的搜索引擎图标就要跟着换。所以
。后面的倒三角点击时显示下拉列表
。
然后是下拉框。如果想要有过渡效果,那个就要包裹在
想要有hover效果的话,用数据驱动的思维,就是比较index 与hoverindex是否相等,如果相等就加class。
Vue.component('logo-picture',{
template :' \
">\
[now].src" @click="toggleFlag"/>\
toggleFlag" class="logoList-arrow"> \
" v-show=" flagShow" class="logoList">\
" :key=" index" @click="changeFlag(index)" @mouseover="flagHover(index)" :class="{selectback: index == hoverindex}">\
item.src" />\
\
\
',
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因为要双向绑定,所以要v-model="keyword"
,还要绑定键盘事件@keyup
,如果按enter就搜索,向下向上就选中给定的返回信息列表。
下面的详情框与
下拉列表差不多。
搜索的话主要是运用$http.jsonp
,还有ES6的语法?回掉好像是Promise的.then()。
Vue.component('search-panel',{
template:'\
\
\
×\
\
\
\
\
{{value}}\
\
\
\
',
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.360.cn/suggest?word=' + this.search + '&encodein=utf-8&encodeout=utf-8').then(function(res) {
this.myData = res.data.s;
}, function() {
});
},
//清除内容
clearInput: function() {
this.search = '';
this.get();
},
//搜索
searchInput: function() {
alert(this.flag)
window.open(this.logoData[this.flag].searchSrc+this.search);
},
//搜索的内容
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;
})
}
})
换了搜索引擎的话,
要换成相应的搜索引擎。这里要新建一个空的Vue对象做中间,因为两个组件不是父子关系。
var bus = new Vue();
//logo-picture里触发事件,并传递参数
bus.$emit("change",index);
//search-panel里监听事件是否发生
var self = this;
bus.$on('change',function(index) {
self.flag = index;
})
这里要注意this问题,$on里this指向bus,所以要保存this才能引用search-panel
.