vue 实时查询

一、概述

先来看一下搜索效果

节流函数

首先,我们来理解一下:节流函数首先是节流,就是节约流量、内存的损耗,旨在提升性能,在高频率频发的事件中才会用到,比如:onresize,onmousemove,onscroll,oninput等事件中会用到节流函数;

实时查询功能原理分析

所谓模糊查询就是不需要用户完整的输入或者说全部输入信息即可提供查询服务,也就是用户可以在边输入的同时边看到提示的信息(其实是查询出来匹配到的信息),百度的搜索功能就是很好的模糊查询的例子;其实模糊查询的原理就是给输入框绑定oninput事件监听用户输入情况,然后每次用户只要在输入框中输入了信息就触发事件进行查询然后实时展示;原理很简单,但是实现起来会有一些问题,我们可以想想,每输入一个字符都会触发事件,那如果我们需要输入很长的信息呢,那查询是不是就得触发多次?ajax连续多次触发,再加上如果我们的方法体中有操作DOM元素的方法,那么必然会给我们的浏览器进入假死甚至崩溃状态;那么我们有没有办法来解决此类问题呢?答案是:有的;(不了解模糊查询功能的同学可以出门右转去百度首页试一下搜索,给你5分钟,我等你回来)

html视图层代码

<div>        
    <div style="margin-top: 15px;">
      <!--    输入框,绑定输入框的值是变量input_value的值,然后对输入框做了事件绑定keyup,在用户输入的时候会触发-->
      <el-input placeholder="请输入关键字" v-model="input_value" class="input-with-select" @keyup.native="throttle" ref="input">
        <el-button slot="append" icon="el-icon-search"></el-button>
      </el-input>
    </div>

    <ul v-show="state">
      <li v-for="(item,index) in list" :key="index" @click="handleInputClick(item)">
        <span>{{item.title}}</span>
      </li>
    </ul>
    <div v-show="IsResultDisplayed" style="position:absolute;top: 70px">
      <span>结果:</span>
      <span>{{ result }}</span>
    </div>
  </div>

从上述代码中我们可以很明显的看到DOM结构,就是一个输入框,我们给输入框加了ref属性是为了方便我们后面操作DOM拿到输入框的值(详情可见ref和$refs的区别博文www.cnblogs.com/dengyao-blo…),然后下面有一个ul列表,不过ul列表是判断展示的;(至于为什么会用v-show而不是v-if,可以点击链接查阅之前的博文 www.cnblogs.com/dengyao-blo…);

js数据逻辑层部分代码

data() {
      return {
        input_value: "", // 搜索关键字
        result:"",  // 搜索结果
        state: false,
        statu: true,
        // 示例数据
        dataList: [
          {id: "1001", title: "我的时代你的时代", content: "我的时代,你的时代(2021年胡一天、李一桐主演的电... - 百度百科"},
          {id: "1002", title: "我的小确幸", content: "我的小确幸 - 百度百科"},
          {id: "1103", title: "我的世界", content: "我的世界Minecraft中国版官方网站——你想玩的,...官方"},
          {id: "1104", title: "我的世界基岩版", content: "我的世界基岩版1.16下载|我的世界基岩版 官方正式版v1.16 ..."},
          {id: "1205", title: "科创版开户条件", content: "开通科创板的条件有两点:一是申请权限开通前20个交易日证券账户及"},
          {id: "1206", title: "科创板股票开户有什么条件", content: "科创板开户条件:近20个交易日,账户平均资产(现金或者股票)达到50万元"},
          {id: "1307", title: "科创板股票交易规则", content: "科创板交易规则 - 百度知道"}
        ],
        list: [],
        IsResultDisplayed: false,  // 结果是否显示
      }
    },
    methods: {
      search() {
        this.list = [];
        //拿到当前input输入框输入的值
        this.input_value = this.$refs.input.value;

        //循环模拟数据的数组
        this.dataList.map((msg) => {
          //拿当前json的id、name、time去分别跟输入的值进行比较
          //indexOf 如果在检索的字符串中没有出现要找的值是会返回-1的,所以我们这里不等于-1就是假设输入框的值在当前json里面找到的情况
          if (msg.title.indexOf(this.input_value) != -1) {
            //然后把当前json添加到list数组中
            this.list.push(msg);
          }
        })

        // 判断展示ul列表,如果输入了就展示没输入就不展示
        if (this.input_value.length > 0) {
          // this.state = true;
          if (this.list.length > 0){
            this.state = true;
          }else {
            this.state = false;
          }
        } else {
          this.state = false;
        }

      },

 js数据逻辑层代码其实不难,主要就是给input绑定了keyup事件,在用户输入的时候会触发search事件,用户每输入一个字符都会触发一次;然后我们通过this.$refs.input.value来获取输入框当前的值并赋值给变量this.input_value,然后我们对this.input_value的长度进行判断来实现对用户是否输入的判断,如果用户输入了我们就把v-show绑定的值state赋值给true,反之则赋值为false;然后我们来用ES6的map方法来循环我们的dataList数组,dataList数组的数据是模拟后台接口数据,通过indexOf方法是否等于-1来进行判断当前json里面是否有输入框中输入的数组,indexOf是javascript提供的操作字符串方法,调用方式:string.indexOf("要查询的值"),如果str中没有要查询的值会返回我们-1,如果有会直接返回给我们查询数据的当前下标;所以我们可以借助indexOf是否等于-1来进行判断当前json中是否有我们要查询的字符串;如果有的话,我们只需要把当前json添加到空数组list中即可,然后li绑定list展示;

到这里我们就可以看到我们要的模糊查询功能已经实现了,但是我们上面讲到模糊查询会影响浏览器的性能,从控制台输入的变量i的值可以看到我们的search方法已经被调用了8次,我们输入的字符越长被调用的次数越多,如果方法里面有操作DOM的行为性能影响会更严重;所以我们现在来加上节流函数来看看:

//节流函数
throttle(){
  //保持this的指向始终指向vue实例
  var that=this;
  if(!that.statu){
    return;
  }
  that.statu=false;
  setTimeout(function(){
    console.log(new Date());
    that.search();
    that.statu=true;
  },1000)
},

我们把我们写的节流函数封装在throttle里面执行,把@keyup绑定的点击事件修改为throttle,当用户输入字符的时候触发节流函数;效果图如下:

我们可以从控制台很清晰的看到当我们使用节流函数的时候,当我们输入了8个字符我们的方法只执行了两次,并且执行时间是每隔一秒执行一次,一个方法执行2次肯定会比执行8次不管是在效率还是在性能方面都会是比较大的提升,用了节流函数之后相对上面没用的节流函数来说,我们极大的实现了性能提升、优化,所以在高频率触发的事件中我们是可以建议用节流函数来进行控制和解决问题的;

test1.vue完整代码如下:

<template>
  <div>        
    <div style="margin-top: 15px;">
      <!--    输入框,绑定输入框的值是变量input_value的值,然后对输入框做了事件绑定keyup,在用户输入的时候会触发-->
      <el-input placeholder="请输入关键字" v-model="input_value" class="input-with-select" @keyup.native="throttle" ref="input">
        <el-button slot="append" icon="el-icon-search"></el-button>
      </el-input>
    </div>

    <ul v-show="state">
      <li v-for="(item,index) in list" :key="index" @click="handleInputClick(item)">
        <span>{{item.title}}</span>
      </li>
    </ul>
    <div v-show="IsResultDisplayed" style="position:absolute;top: 70px">
      <span>结果:</span>
      <span>{{ result }}</span>
    </div>
  </div>
</template>

<script>
  export default {
    name: "test1",
    data() {
      return {
        input_value: "", // 搜索关键字
        result:"",  // 搜索结果
        state: false,
        statu: true,
        // 示例数据
        dataList: [
          {id: "1001", title: "我的时代你的时代", content: "我的时代,你的时代(2021年胡一天、李一桐主演的电... - 百度百科"},
          {id: "1002", title: "我的小确幸", content: "我的小确幸 - 百度百科"},
          {id: "1103", title: "我的世界", content: "我的世界Minecraft中国版官方网站——你想玩的,...官方"},
          {id: "1104", title: "我的世界基岩版", content: "我的世界基岩版1.16下载|我的世界基岩版 官方正式版v1.16 ..."},
          {id: "1205", title: "科创版开户条件", content: "开通科创板的条件有两点:一是申请权限开通前20个交易日证券账户及"},
          {id: "1206", title: "科创板股票开户有什么条件", content: "科创板开户条件:近20个交易日,账户平均资产(现金或者股票)达到50万元"},
          {id: "1307", title: "科创板股票交易规则", content: "科创板交易规则 - 百度知道"}
        ],
        list: [],
        IsResultDisplayed: false,  // 结果是否显示
      }
    },
    methods: {
      search() {
        this.list = [];
        //拿到当前input输入框输入的值
        this.input_value = this.$refs.input.value;

        //循环模拟数据的数组
        this.dataList.map((msg) => {
          //拿当前json的id、name、time去分别跟输入的值进行比较
          //indexOf 如果在检索的字符串中没有出现要找的值是会返回-1的,所以我们这里不等于-1就是假设输入框的值在当前json里面找到的情况
          if (msg.title.indexOf(this.input_value) != -1) {
            //然后把当前json添加到list数组中
            this.list.push(msg);
          }
        })

        // 判断展示ul列表,如果输入了就展示没输入就不展示
        if (this.input_value.length > 0) {
          // this.state = true;
          if (this.list.length > 0){
            this.state = true;
          }else {
            this.state = false;
          }
        } else {
          this.state = false;
        }

      },
      //节流函数
      throttle(){
        //保持this的指向始终指向vue实例
        var that=this;
        if(!that.statu){
          return;
        }
        that.statu=false;
        setTimeout(function(){
          console.log(new Date());
          that.search();
          that.statu=true;
        },1000)
      },
      // 处理输入点击
      handleInputClick(item){
        this.input_value = item.title
        // 触发正式查询api操作
        // this.$message.success('请求api,关键字'+item.title)
        // 清空关键字列表
        this.list = []
        // 显示结果
        this.IsResultDisplayed = true
        this.state = false
        this.result = item.content
      },
    }
  }
</script>

<style scoped>
  ul {
    list-style: none;
    top: 0px;
    left: 0px;
    right: 0px;
    /*margin-left: -40px;*/
    z-index: 999;
    /*overflow:auto;*/
    position:relative;
    background-color: white;
    border: 2px solid #4e71f2!important;
  }
  ul :hover {
    cursor: pointer;
    /*background-color: #4c9fff;*/
    color: #4e71f2;
  }
  li {
    list-style: none;
    top: 0px;
    left: 0px;
    right: 0px;
    padding: 0px 0px 8px;
    margin-left: -35px;
  }
</style>

注意:运行前,确保正确安装了ElementUI模块。

运行成功后访问页面,和本文开头一样的效果的。

本文参考链接:

https://juejin.cn/post/6844903967088967694

原文地址:https://cloud.tencent.com/developer/article/1808625

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340