1. 程式人生 > 程式設計 >Vue文字模糊匹配功能如何實現

Vue文字模糊匹配功能如何實現

模糊匹配功能在下拉選單的元件中用的非常多,於是打算寫幾個demo看看細節上是如何實現的。

一、最簡單的模糊匹配:計算屬性

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <input type="text" v-model="message">
    <ul>
      <li v-for="(option,index) in matchedOptions" :key="index">{{ option }}</li>
    </ul>
  </div>
  <script src="./vue.js"></script>
  <script>
    new Vue({
      el: '#app',data: {
        message: '',options: ['html','css','javascript']
      },computed: {
        matchedOptions() {
          if (this.message !== '') {
            return this.options.filter(option => option.includes(this.message))
          }
          return this.options
        }
      }
    })
  </script>
</body>
</html>

在上面的例子中,計算屬性matchedOptions會在文字框內容message變化時篩選options裡的資料,效果圖如下所示:

Vue文字模糊匹配功能如何實現

二、使用作用域插槽實現

使用插槽主要是為了使該功能元件化:在select元件中插入option,然後option通過作用域插槽從select中獲取文字值:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <my-select>
      <template #default="{ message }">
        <ul>
          <li v-for="(option,index) in options" :key="index" v-show="option.includes(message)">{{ option }}</li>
        </ul>
      </template>
    </my-select>
  </div>
  <script src="./vue.js"></script>
  <script>
    Vue.component('my-select',{
      template: `
        <div class="my-select">
          <input type="text" v-model="message">
          <slot :message="message"></slot>
        </div>
      `,data() {
        return {
          message: ''
        }
      }
    })
    new Vue({
      el: '#app',data: {
        options: ['html','javascript']
      }
    })
  </script>
</body>
</html>

全域性註冊了my-select元件後,可以刪除app裡的message資料,使用v-show來控制選項的顯示,執行效果和計算屬性方式相同。缺點就是無法單檔案化(剛學vue沒多久,不知道怎麼在單檔案裡使用作用域插槽,試過直接把template裡的東西封裝成my-option好像並不管用)

三、混入廣播和派發方法在獨立元件中實現模糊匹配

首先需要一個emitter檔案:

/**
 * 子元件廣播事件
 * @param {string} componentName 子元件名
 * @param {string} eventName 事件名
 * @param {...any} params 事件引數
 */
function _broadcast(componentName,eventName,...params) {
  this.$children.forEach(child => {
    if (child.$options.name === componentName) {
      child.$emit(eventName,...params)
    }
    _broadcast.call(child,componentName,...params)
  })
}

/**
 * 父元件派發事件
 * @param {string} componentName 父元件名
 * @param {string} eventName 事件名
 * @param {...any} params 事件引數
 */
function _dispatch(componentName,...params) {
  if (this.$parent) {
    if (this.$parent.$options.name === componentName) {
      this.$parent.$emit(eventName,...params)
    }
    _dispatch.call(this.$parent,...params)
  }
}

/**
 * mixin
 */
export default {
  methods: {
    broadcast(componentName,...params) {
      _broadcast.call(this,...params)
    },dispatch(componentName,...params) {
      _dispatch.call(this,...params)
    }
  }
}

注意,這裡的$children和$parent都是指具有dom父子關係的vue元件。

最後,通過設定查詢條件來控制子元件的顯示與隱藏即可實現實時模糊搜尋。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。