vue实现简单搜索功能

目录

      • 1、概述
      • 2、功能逻辑
        • 2.1功能流程
        • 2.2 流程图
      • 3、功能实现
        • 3.1 vue组件化
        • 3.2 代码
        • 3.3 动态效果

1、概述

在vue项目中,搜索功能是我们经常需要使用的一个场景,最常用的是在列表数据中搜索一个想要的,今天的例子就是我们实现vue从列表数据中搜索,并展示。如下图所示:
vue实现简单搜索功能_第1张图片

2、功能逻辑

2.1功能流程

这里我们进行简单搜索功能,搜索逻辑是只要用户输入值与产品的名称进行模糊匹配,符合条件的数据进行展示,不符合条件的数据过滤。流程描述如下:

  1. 用户点击搜索框,输入内容;
  2. 检测到搜索框值变化,取用户输入值;
  3. 对用户输入值进行判断,若为空,则展示原列表,不为空则进行筛选;
  4. 将用户输入值与所有列表数据进行遍历匹配,若匹配,则展示匹配条目,完成搜索。

2.2 流程图

vue实现简单搜索功能_第2张图片
这张图仅代表最简单的搜索流程,若需要进行一些复杂的处理,可以进行修改,比如说匹配的商品名称关键字变色等。

3、功能实现

3.1 vue组件化

实现如上图功能,我们肯定是使用vue的组件特性,将搜索以及,产品列表抽成组件,以提高代码复用性,抽成组件之后,该页面将由三个部分组成,数据在以下三个组件之间传递:

  • 父组件:主页面,用于数据逻辑处理
  • 搜索组件:给父组件传递用户输入值;
  • 列表:展示从父组件接收的值。

3.2 代码

父组件:index.vue

<template>
  <div>
    <title-bar :title="title" @goBack="goback">title-bar>
    <search-input 
      :plhText="searchPlhText"
      @input-changed="searchInputChange"
    >search-input>
    <div v-for="(prd,index) in productListRst" :key="index">
      <prd-item :prd="prd" @toPrdDetail="toPrdDetail">prd-item>
    div> 
  div>
template>
<script>
import TitleBar from "@/components/TitleBar";
import SearchInput from "./components/SearchInput";
import PrdItem from './components/PrdItem';
export default {
      
  name: "",
  components: {
      
    TitleBar,
    SearchInput,
    PrdItem
  },
  data() {
      
    return {
      
      title: "产品列表",
      searchPlhText: "请输入产品名称",
      productList: {
      }, // 产品列表
      productListRst: {
      }, // 搜索筛选之后的产品列表
    }
  },
  created() {
      
    // 初始化页面参数,按照生命周期,子组件需要的参数父组件需要在created生命周期取值
    this.initParams();
  },
  methods: {
      
    // 返回方法
    goback() {
      
      // this.$emit("GoBack");
    },
    // 初始化页面参数,获取产品列表
    initParams() {
      
      this.productList = [
        {
      
          imgPath: 'apple-1001.png',
          name: 'Apple iPad Air 平板电脑(2020新款)',
          price: '4799.00',
          sale: '5',
          ranking: '10000+评价 平板热卖第5名',
          prdShopName: 'Apple官方旗舰店'
        },
        {
      
          imgPath: 'apple-1002.png',
          name: 'Apple iPhone 11手机',
          price: '4999.00',
          sale: '5',
          ranking: '375万+评价',
          prdShopName: 'Apple官方旗舰店'
        },
        {
      
          imgPath: 'apple-1003.jpg',
          name: 'Apple AirPods 配充电盒 Apple蓝牙耳机',
          price: '1246.00',
          sale: '5',
          ranking: '200万+评价',
          prdShopName: 'Apple官方旗舰店'
        },
      ];
      this.productListRst = this.productList;
    },
    // 每次search框变化则进行筛选,对数据进行逻辑处理
    searchInputChange(value) {
      
      // 若未输入值,则展示所有数据
      if(null === value || undefined === value){
      
        this.productListRst = this.productList;
      } else {
      
        this.productListRst = []; // 结果列表置空
        let regStr =  '';
        // 初始化正则表达式
        for(let i=0; i<value.length; i++){
      
          regStr = regStr + '(' + value[i] + ')([\\s]*)'; //跨字匹配
        }
        let reg = new RegExp(regStr);
        console.log(reg);
        for(let i=0; i<this.productList.length; i++){
      
          let name = this.productList[i].name; //按照名字匹配
          let regMatch = name.match(reg);
          if(null !== regMatch) {
      // 将匹配的数据放入结果列表中
             this.productListRst.push(this.productList[i]);
          }
        }
      }
    },
    // 去往产品详情页
    toPrdDetail(){
      
      this.$router.push({
      path: 'detail'})
    }
  }
};
script>
<style scoped>
#page-title {
      
  width: 100%;
  background-color: #fff;
  display: flex;
  justify-content: center;
}
.backImg {
      
  width: 20px;
}
style>

主要的逻辑处理是 searchInputChange,对于更复杂的搜索逻辑,也可以在里面进行处理。
搜索组件:Search.vue

<template>
  <div class="search-box">
    <div class="search-input">
      <img src="@/assets/images/search.png" />
      <input
        type="text"
        :placeholder="plhText"
        maxlength="10"
        @change="inputChange"
        v-model="inputValue"
      />
    </div>
  </div>
</template>
<script>
export default {
     
  name: "searchInput", // 搜索输入框
  props: {
     
    // input框占位文字
    plhText: {
     
      type: String,
      default: "请输入搜索内容"
    }
  },
  data() {
     
    return {
     
      inputValue: "" //输入框的值
    };
  },
  methods: {
     
    // 每次输入框变化刷新列表
    inputChange() {
     
      // 使用emit给父组件传值
      this.$emit('input-changed', this.inputValue);
    }
  }
};
</script>

列表组件:productList.vue

<template>
  <div class="prd-item" @click="toPrdDetail">
    <img :src="require('@/assets/images/'+prd.imgPath)">
    <div class="prd-discription">
      <div class="prd-title">{
    { prd.name }}div>
      <div class="prd-sellInfo">
        <div class="prd-price">{
    { prd.price }}div>
        <div class="prd-saleLable" v-if="prd.sale.lenght!==0">
          <label>12期免息label>
          <span>新品span>
        div>
        <div class="prd-ranking">{
    { prd.ranking }}div>
        <div class="prd-shop">{
    { prd.prdShopName }}div>
      div>
    div>
  div>
template>
<script>
export default {
      
  props: {
      
    // 传入产品对象,必传属性为imgPath,name,price,shop
    prd: {
      
      type: Object,
    }
  },
  methods: {
      
    // 跳转产品详情页面
    toPrdDetail() {
      
      this.$emit("to-prd-detail",this.prd.Id);
    }
  }
};
script>

以上代码为部分代码,css代码不包含在内。

3.3 动态效果

以上代码实现的效果如下动态图:

你可能感兴趣的:(vue,前端,vue)