基于Vue.js实现简单搜索框

在github上看到的练习,看个遍代码后自己再练一遍,先放原址:https://github.com/lavyun/vue-demo-search

主要用到的知识很简单,简单的vuejs2.0的知识就够了。源码用了.vue构建和ES6,用了webpack打包等等。我资历还浅,先用一个简单的.js的写。

先看效果

这里有两个组件,一个组件是logo部分的,一个是搜索框部分的。

html

html很简单,就是引用两个组件。

<div id="app">
 <logo-picture></logo-picture>
 <search-panel></search-panel>
</div>

//js还要实例#app
var app = new Vue({
 el: "#app"
})

logo

先来分析,首先一个<img />显示搜索引擎的图片,这里要响应式的,下面选择了不同的搜索引擎图标就要跟着换。所以<img :src="items[now].src" />。后面的倒三角点击时显示下拉列表<span @click="toggleFlag"> </span>。
然后是下拉框。如果想要有过渡效果,那个就要包裹在<transition-group中,然后遍历li,记住元素要指定唯一的key。
想要有hover效果的话,用数据驱动的思维,就是比较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因为要双向绑定,所以要v-model="keyword",还要绑定键盘事件@keyup,如果按enter就搜索,向下向上就选中给定的返回信息列表。
下面的详情框与<logo-picture>下拉列表差不多。
搜索的话主要是运用$http.jsonp,还有ES6的语法?回掉好像是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.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;
 })
 }
})

两个兄弟组件通信的问题

<logo-picture>换了搜索引擎的话,<search-panel>要换成相应的搜索引擎。这里要新建一个空的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.

本文已被整理到了《Vue.js前端组件学习教程》,欢迎大家学习阅读。

关于vue.js组件的教程,请大家点击专题vue.js组件学习教程进行学习。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 基于vue2.0实现的级联选择器

    基于Vue的级联选择器,可以单项,二级, 三级级联,多级级联 web开发中我们经常会遇到级联选择器的问题,尤其是在表单中,无外乎几种情况: 单个级联 (下拉选择框,单选) 单个级联 (多项选择) 二级联动 (省份和城市联动) 三级联动 (省市区联动) 在jquery中有很多好用的插件,比如select2, 单选,多选的功能都具备. 本文探讨一下在vue中的实现级联选择器,自己在项目中碰到过以下两种情况的后端数据,查阅资料后也证实了这两种数据的合理性: 预览地址 github地址 1 后端处理数

  • 基于Vue实现tab栏切换内容不断实时刷新数据功能

    先说一下产品需求,就是有几个tab栏,每个tab栏对应的ajax请求不一样,内容区域一样,内容为实时刷新数据,每3s需要重新请求,返回的数据在内容区域展示,每点击一次tab栏需停止其他tab栏ajax请求,防止阻塞,首次加载页面的时候又不能5个ajax同时请求,只需要请求第一个就好 也没有必要建立5个区域,控制显示隐藏,浪费性能,业务代码就不贴了,把大概原理的代码贴上来 先是用jq实现了一版 <!DOCTYPE html> <html lang="en"> &l

  • 基于vue.js轮播组件vue-awesome-swiper实现轮播图

    一般做移动端轮播图的时候,最常用的就是Swiper插件了,而vue.js也有一个轮播组件vue-awesome-swiper,用法跟swiper相似. 1.安装vie-awesome-swiper nam install vue-awesome-swiper --save-dev 2.引用vie-awesome-swiper组件,这里我是用vie-cli创建的项目,在main.js: import VueAwesomeSwiper from 'vue-awesome-swiper'; Vue.u

  • 基于VUE选择上传图片并页面显示(图片可删除)

    基于VUE选择上传图片并在页面显示,图片可删除,具体内容如下 demo例子: 依赖文件:jqueryform HTML文本内容: <template> <div id="accident"> <div class="wrapper"> <i class="icon-pic"></i>相关照片 <button type="button" @click="

  • 基于Vue.js的表格分页组件

    一.Vue.js简介 1.Vue的主要特点: (1) 简洁 (2) 轻量 (3)快速 (4) 数据驱动 (5) 模块友好 (6) 组件化 (1) 简洁 下面看一段Angular的实现双向绑定的代码 // html <body ng-app="myApp"> <div ng-controller="myCtrl"> <p>{{ note }}</p> <input type="text" ng-

  • 基于Vue实现图书管理功能

    本文实例为大家分享了vue简单的图书管理具体代码,供大家参考,具体内容如下 <table class="table table-bg table-border table-bordered"> <tr> <th>ID</th> <th>书名</th> <th>作者</th> <th>价格</th> <th>操作</th> </tr>

  • 基于Vuejs实现购物车功能

    本文实例为大家分享了Vuejs购物车实现代码,供大家参考,具体内容如下 html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>我的vue购物车</title> <link rel="stylesheet" href="css/bootstrap.min.css&q

  • 基于vuejs+webpack的日期选择插件

    基于vuejs+webpack环境使用的日期选择插件,希望大家喜欢. 支持单选和多选日期 支持限定开始和结束日期范围选择. 支持小时分钟 需要引入fontawesome.io 的图标库. Options :show 是否显示 :type date|datetime :value 默认值 :begin 可选开始时间 :end 可选结束时间 :x 显示x坐标 :y 显示y坐标 :range 是否多选 test.vue <template> <input type="text&quo

  • 基于vue.js实现图片轮播效果

    轮播图效果: 1.html <template> <div class="shuffling"> <div class="fouce fl"> <div class="focus"> <ul class="showimg"> <template v-for='sd in shufflingData'> <li v-if='shufflingId==$

  • 基于vue.js实现侧边菜单栏

    侧边菜单栏应该是很多项目里必不可少的 自己手写了一个 下面是效果图 下面就说一下实现的过程 还是比较简单的 首先导入一下需要的文件 <link rel="stylesheet" type="text/css" href="bootstrap/css/bootstrap.min.css" rel="external nofollow" > <link rel="stylesheet" typ

随机推荐