瀏覽代碼

[ADD] fuzzy search in variants

Gogs 7 年之前
父節點
當前提交
db1ad44642
共有 3 個文件被更改,包括 85 次插入25 次删除
  1. 49 2
      src/components/ProductSelector.vue
  2. 20 19
      src/components/ProductsSearcher.vue
  3. 16 4
      src/store/modules/products.js

+ 49 - 2
src/components/ProductSelector.vue

@@ -1,13 +1,14 @@
 <template lang="pug">
     .product-selector
         modal(name="product-selector" transition="nice-modal-fade" height="500")
-            input.variant-searcher(type="search" placeholder="Buscar una variante de producto")
+            input.variant-searcher(type="search" placeholder="Buscar una variante de producto" v-model="search")
             .product-variants
                 product-variant(v-for="variant in variants" :key="variant.id" :data="variant")
 </template>
 
 <script>
-    import { mapGetters } from 'vuex'
+    import { mapGetters, mapActions } from 'vuex'
+    import Fuse from 'fuse.js'
     import ProductVariant from '@/components/ProductVariant'
 
     export default {
@@ -17,6 +18,52 @@
         computed: mapGetters({
             variants: 'getVariants'
         }),
+        methods: {
+            initFuse() {
+                if (this.fuse) {
+                    this.fuse.setCollection(this.variants)
+                    return
+                } 
+
+                this.fuse = new Fuse(this.variants, {
+                    shouldSort: true,
+                    threshold: 0.4,
+                    location: 0,
+                    distance: 100,
+                    maxPatternLength: 32,
+                    minMatchCharLength: 1,
+                    keys: [
+                        'name',
+                        'display_name',
+                        'ean13',
+                    ]
+                })
+            },
+            fuzzySearch() {
+                this.results = this.fuse.search(this.search)
+            },
+            ...mapActions([
+                'filterVariants'
+            ])
+        },
+        watch: {
+            variants() {
+                this.initFuse()
+            },
+            search() {
+                this.fuzzySearch()
+            },
+            results() {
+                this.filterVariants(this.results)
+            }
+        },
+        data() {
+            return {
+                search: '',
+                results: [],
+                fuse: null,
+            }
+        },
         mounted() {
             this.$store.watch(state => {
                 return state.products.selectedProduct

+ 20 - 19
src/components/ProductsSearcher.vue

@@ -8,30 +8,13 @@
     import Fuse from 'fuse.js'
 
     export default {
-        data() {
-            return {
-                search: '',
-                results: [],
-                fuse: null,
-            }
-        },
         computed: mapGetters({
             products: 'getProducts'
         }),
-        watch: {
-            search() {
-                this.fuzzySearch()
-            },
-            results() {
-                this.filterProducts(this.results)
-            },
-            products() {
-                this.initFuse()
-            }
-        },
         methods: {
             initFuse() {
                 if (this.fuse) {
+                    this.fuse.setCollection(this.products)
                     return
                 }
 
@@ -55,7 +38,25 @@
             ...mapActions([
                 'filterProducts'
             ])
-        }
+        },
+        watch: {
+            products() {
+                this.initFuse()
+            },
+            search() {
+                this.fuzzySearch()
+            },
+            results() {
+                this.filterProducts(this.results)
+            }
+        },
+        data() {
+            return {
+                search: '',
+                results: [],
+                fuse: null,
+            }
+        },
     }
 </script>
 

+ 16 - 4
src/store/modules/products.js

@@ -1,18 +1,23 @@
 const state = {
     products: [],
-    filtered: [],
+    filteredProducts: [],
+    filteredVariants: [],
     selectedProduct: null
 }
 
 const getters = {
     getProducts (state) {
-        return state.filtered.length === 0 ? state.products : state.filtered
+        return state.filteredProducts.length === 0 ? state.products : state.filtered
     },
     getSelectedProduct(state) {
         return state.selectedProduct
     },
     getVariants(state) {
-        return !!state.selectedProduct ? state.selectedProduct.variants : []
+        if (!!state.selectedProduct) {
+            return state.filteredVariants.length === 0 ? state.selectedProduct.variants : state.filteredVariants
+        }
+
+        return []
     }
 }
 
@@ -24,8 +29,12 @@ const mutations = {
         state.selectedProduct = payload.product
     },
     applyProductsFilter(state, payload) {
-        state.filtered = payload
+        state.filteredProducts = payload
+    },
+    applyVariantsFilter(state, payload) {
+        state.filteredVariants = payload
     }
+    
 }
 
 const actions = {
@@ -70,6 +79,9 @@ const actions = {
     },
     filterProducts({ commit }, payload) {
         commit('applyProductsFilter', payload)
+    },
+    filterVariants({ commit }, payload) {
+        commit('applyVariantsFilter', payload)
     }
 }