Vue百度搜索框实例

百度搜索框实例

  • 思路:
    1. 通过vue.js和bootstrap.js来构建搜索框和列表页面架构;
    2. 文本输入框通过v-model设置与应用的双向绑定,列表框通过v-for来遍历,获取遍历的数据动态绑定在列表中;
    3. 设置@keyup事件,触发函数,函数内,通过vue-resource插件,进行jsonp请求数据,请求百度服务器上的数据,通过设置params中的wd值来进行查找数据,赋值给ary,遍历到列表中;
    4. 实现文本输入框输入内容,列表同时更新数据;
    5. 设置列表中第一条数据点亮效果,动态绑定样式,利用:class="{active:index===i}",意思为,当index值与i值相等时,设置类名active;其中index为data中设置的值,i为遍历ary数组时的列表数据索引值;
    6. 设置列表中第一条数据点亮,即设置index的初始值为0;
    7. 设置下键效果:按键盘中的下键,实现列表数据的变化和点亮;同时输入框中的数据显示选中的列表中的数据;
      • 设置@keydown.down事件,触发putDown函数,函数中改变this.index的值,让其累加,然后通过%来控制上限;
    8. 设置上键效果:按键盘中的上键,实现列表数据的变化和点亮;同时输入框中的数据显示选中的列表中的数据;
      • 设置@keydown.up事件,触发putUp函数,函数中改变this.index的值,使其累减,然后判断边界值;控制下限;
      • 注意:按上键时,文本框中会默认选中文字的最前面,所以需要阻止默认事件,即设置@keydown.up.prevent事件;
    9. 设置上下键的效果中,需要注意,在更新输入框中的数据后,会执行keydown事件,重新进行数据获取,然后更新列表数据,所以,需要在keydown事件函数中,设置条件判断,通过事件对象e.keyCode来判断上下键,当按下上下键时,阻止搜索程序;
    10. 设置回车键效果:当按下enter键后,搜索文本框中的内容;
      • 设置@keydown.enter事件,触发goSearch函数,函数中利用window.open(url)来打开搜索地址;
  • 注意点:
    1. 文本框必须绑定keyup事件,不能绑定keydown事件;在获取数据时,必须判断msg是否为空,如果为空,则无需发送请求,并赋值ary为空;
  • 实例代码:
 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>百度搜索框</title>
     <link rel="stylesheet" href="css/bootstrap.css"/>
 </head>
 <body>
 <div class="container">
     <div id="app">
         <h1>百度搜索</h1>
         <form>
             <div class="form-group">
                 <input type="text" class="form-control" id="text" v-model="msg" @keyup="getData" @keydown.down="putDown" @keydown.up.prevent="putUp" @keydown.enter="goSearch"/>
             </div>
         </form>
         <ul class="list-group">
             <li v-for="(item,i) in ary" class="list-group-item" :class="{active:index===i}">{{item}}</li>
         </ul>
     </div>
 </div>
 <script src="js/vue.js"></script>
 <script src="js/vue-resource.js"></script>
 <script>
     new Vue({
         el:"#app",
         data:{
             msg:"",
             ary:[],
             index:0
         },
         methods:{
             getData(e){
                 //当按下键和上键时,阻止搜索功能;
                 if(e.keyCode===38 || e.keyCode===40) return;
                 //发送jsonp请求,跨域获取数据
                 if(this.msg!==""){
                     this.$http.jsonp("https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su",{
                         params:{
                             wd:this.msg
                         },
                         jsonp:"cb"
                     }).then(res=>{
                         this.ary=res.body.s;
                     })
                 }else{
                     this.ary=[];
                 }
             },
             putDown(){
                 //按下键,让对应的变亮,主要是改变this.index的值
                 this.index++;
                 this.index%=this.ary.length;
                 //更新文本框中的数据
                 this.msg=this.ary[this.index];
             },
             putUp(){
                 //按上键,让对应的变亮
                 this.index--;
                 if(this.index<0){
                     this.index=this.ary.length-1;
                 }
                 this.msg=this.ary[this.index];
             },
             goSearch(){
                 //按下回车键,跳转搜索
                 window.open(`https://www.baidu.com/s?wd=${this.msg}`,"_blank")
             }
         }
     })
 </script>
 </body>
 </html>

升级版百度搜索框实例

  • 思路:
    1. 引入bootstrap插件;写出静态页面;
    2. 通过vue-resource插件,向百度服务器发送请求,获取数据; 文本框绑定keyup事件,当键盘抬起时,获取新的输入值,然后在获取数据;
    3. 获取数据赋值dataAry变量,通过v-for遍历插入dom结构;
    4. 功能1:通过按向上,向下键来使对应列表中的内容赋值到文本输入框内,并且该列被点亮;
      • 文本框需绑定两个事件:keydown.up和keydown.down 指的是键盘上向下和向上按键事件;注意:当向上按键时,光标会在文本的最前面,所以需要阻止默认事件,则需绑定keydown.up.prevent
      • 设置变量n,作为整个项目中的介质,目的:通过设置n的值,来点亮指定的列表;
      • 在html中,绑定li时,通过v-bind来绑定class,设置为三目,通过判断index和n-1值是否相等,来设置类名,进而点亮列表;
      • 在两个事件触发的函数中,对n进行自加和自减处理,设置边界值判断;
      • 对文本框内数据进行赋值:在事件函数中,通过n的值来获取指定列表的索引值,进而在dataAry数组中找到对应的元素内容,赋值给msg即可;
      • 当向上向下回到文本框时,让文本框中的数据为最开始输入的内容;方法:设置变量initVal,用来存储最初的输入值,赋值位置为getData()函数中,在每次向百度服务器发送请求之前,赋值给initVal;
      • 注意:文本框绑定了keyup事件,当向下和向上按键触发后,也会再次触发,所以,必须阻止两个事件的执行;方法:通过事件对象e来获取按键码,进而阻止指定按键码的执行;
    5. 功能2:光标移入列表后,列表项被点亮;文本框中的内容不改变;并且,光标移出列表后,点亮消失;满足:当光标移入一个列表后,该列表被点亮,然后按上下键,列表会依次被点亮;
      • 给每个列表绑定两个事件:mouseenter和mouseleave事件;光标移入移出事件;
      • 事件函数中,通过获取列表的索引值,来赋值n的值;进而实现点亮功能;
      • 移出函数中,赋值n值为文本框对应的值;
    6. 功能3:当按键盘enter键后,跳转到新的页面搜索;当鼠标点击列表项时,跳转到新的页面加载;
      • 给文本输入框绑定keydown.enter事件;
      • 给列表项绑定click事件;
      • 两个事件,可以绑定同一个函数;
      • 跳转到新的页面加载:通过window.open(url)实现;window.href=url实现在本页面中加载;
      • 注意:keydown.enter事件绑定时,为传入实参,则触发后会给函数体默认传入事件对象e,而click事件因为赋值实参,所以不会默认传入事件对象e;所以需要给函数体设置两个形参;判断第二个形参是否被赋值实参,来判断是触发的哪个事件;进而进行不同操作;
  • 注意点:
    1. 文本输入框中绑定keyup事件,不能绑定keydown事件,当键盘抬起时,获取msg,然后获取数据;
    2. 在获取数据之前,必须判断msg是否为空,若为空,则无需在发送请求获取数据;
    3. @keydown.enter@click事件;1)在绑定事件时,如果不传实参,则事件触发后默认向函数体中传入一个事件对象e;2)在绑定事件时,若给函数体传了实参值,则事件在触发后,不会再默认传入事件对象,若需要获取事件对象,则可在传入实参时,传入$event实参;
    4. 鼠标移入移出事件@mouseenter和@mouseleave;
    5. window.location.href=url指的是:在本页面中加载新页面;
      window.open(url)指的是:在新的页面中加载新页面;
  • 实例代码:
 <!DOCTYPE html>
 <html lang="zh-CN">
 <head>
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
     <title>升级版百度搜索框实例</title>
 
     <!-- Bootstrap -->
     <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">
     <style>
         h1{
             margin: 20px 0 10px;
         }
         .input-group{
             width: 100%;
         }
         .input-group .form-control:last-child{
             border-top-left-radius: 6px;
             border-bottom-left-radius: 6px;
         }
         .input-group .form-control:first-child{
             border-top-right-radius: 6px;
             border-bottom-right-radius: 6px;
         }
         .list-group{
             margin: 15px 0;
         }
         .list-group .list-group-item{
             cursor: pointer;
         }
         .bgc{
             background-color: lightskyblue;
         }
     </style>
 
     <!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 -->
     <!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 -->
     <!--[if lt IE 9]>
     <script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
     <script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
     <![endif]-->
 </head>
 <body>
 <div class="container">
     <div id="app">
         <h1>百度搜索框实例</h1>
         <div class="input-group">
             <input type="text" class="form-control" v-model="msg" @keyup="getData" @keydown.up.prevent="putUp" @keydown.down="putDown" @keydown.enter="goSearch"/>
         </div>
         <ul class="list-group">
             <li class="list-group-item" v-for="(item,index) in dataAry" :class="index===n-1?'bgc':''" :key="index" @mouseenter="mouseEnter(index)" @mouseleave="mouseLeave(index)" @click="goSearch(index,item)">{{item}}</li>
         </ul>
     </div>
 </div>
 <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
 <script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
 <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
 <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
 <!--引入vue.js-->
 <script src="./js/vue.js"></script>
 <!--引入vue-resource.js-->
 <script src="./js/vue-resource.js"></script>
 <script>
     new Vue({
         el: "#app",
         created(){
             if(this.msg=""){
                 this.dataAry=[];
             }
         },
         data: {
             initVal:this.msg,
             msg: "",
             n: 0,
             dataAry: []
         },
         methods: {
             getData(e){
                 //当按键为向上和向下时,无需获取新的数据
                 if(e.keyCode===38 || e.keyCode===40) return;
                 if(this.msg!==""){
                     this.initVal=this.msg;
                     this.n=0;
                     this.$http.jsonp("https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su",{
                         params: {
                             wd: this.msg
                         },
                         jsonp: "cb"
                     }).then(res => {
                         var ary=res.body.s;
                         if(ary.length>=6){
                             ary.splice(6);
                         }
                         this.dataAry=ary;
                     },err => {
                         console.log(err);
                     })
                 }else{
                     this.dataAry=[];
                 }
             },
             putUp(){
                 this.n--;
                 if(this.n===0){
                     //赋值为原来输入框内的数据
                     this.msg=this.initVal;
                     return;
                 }
                 if(this.n<0){
                     if(this.dataAry.length>0){
                         this.n=this.dataAry.length;
                     }
                 }
                 //将数组内容赋给文本输入框
                 this.msg=this.dataAry[this.n-1];
             },
             putDown(){
                 this.n++;
                 if(this.n>this.dataAry.length){
                     this.msg=this.initVal;
                     this.n=0;
                     return;
                 }
                 this.msg=this.dataAry[this.n-1];
             },
             mouseEnter(index){
                 this.n=index+1;
             },
             mouseLeave(){
                 //移出后,背景色消失;
                 this.n=0;
             },
             goSearch(e,item){
                 //知识点:@keydown.enter和@click事件;1)在绑定事件时,如果不传实参,则事件触发后默认向函数体中传入一个事件对象e;2)在绑定事件时,若给函数体传了实参值,则事件在触发后,不会再默认传入事件对象,若需要获取事件对象,则可在传入实参时,传入$event实参;
                 //筛选,判断第二个参数是否会传入,若传入了,则为点击事件触发,则需将文本输入框内的数据赋值为列表框内的数据,并跳转页面
                 if(item!==undefined){
                     //如果不等于undefined,则为click事件
                     this.msg=item;
                 }
                 //跳转新页面搜索
                 window.open("https://www.baidu.com/s?wd="+this.msg);
                 this.n=0;
             }
         }
     })
 </script>
 </body>
 </html>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  •   JavaScript 与 HTML 之间的交互是通过事件实现的。   事件,就是文档或浏览器窗口中发生的一些特...
    霜天晓阅读 3,464评论 1 11
  • 第3章 基本概念 3.1 语法 3.2 关键字和保留字 3.3 变量 3.4 数据类型 5种简单数据类型:Unde...
    RickCole阅读 5,074评论 0 21
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,065评论 1 32
  • 1、窗体 1、常用属性 (1)Name属性:用来获取或设置窗体的名称,在应用程序中可通过Name属性来引用窗体。 ...
    Moment__格调阅读 4,417评论 0 11
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,327评论 0 17