Searcher.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <template lang="pug">
  2. input.searcher(type='search' :placeholder='placeholder' :style='{ width, height }' v-model='search')
  3. </template>
  4. <script>
  5. import Fuse from 'fuse.js'
  6. export default {
  7. props: {
  8. items: {
  9. type: Array,
  10. default: [],
  11. required: true
  12. },
  13. placeholder: {
  14. type: String,
  15. default: 'Buscar...'
  16. },
  17. width: {
  18. type: String,
  19. default: '100%'
  20. },
  21. height: {
  22. type: String,
  23. default: '35px'
  24. },
  25. shouldSort: {
  26. type: Boolean,
  27. default: true
  28. },
  29. threshold: {
  30. type: Number,
  31. default: 0.4,
  32. },
  33. location: {
  34. type: Number,
  35. default: 0
  36. },
  37. distance: {
  38. type: Number,
  39. default: 100
  40. },
  41. maxPatternLength: {
  42. type: Number,
  43. default: 32
  44. },
  45. minMatchCharLength: {
  46. type: Number,
  47. default: 1
  48. },
  49. keys: {
  50. type: Array,
  51. default: [],
  52. required: true
  53. },
  54. mode: {
  55. type: String,
  56. default: 'fuzzy'
  57. }
  58. },
  59. watch: {
  60. items(values) {
  61. if (this.mode !== 'fuzzy') {
  62. return
  63. }
  64. this.fuse.setCollection(values)
  65. },
  66. search(value) {
  67. this.performSearch(value.trim())
  68. },
  69. results(values) {
  70. this.$emit('onSearch', values)
  71. }
  72. },
  73. methods: {
  74. initFuse() {
  75. this.fuse = new Fuse(this.items, {
  76. shouldSort: this.shouldSort,
  77. threshold: this.threshold,
  78. location: this.location,
  79. distance: this.distance,
  80. maxPatternLength: this.maxPatternLength,
  81. minMatchCharLength: this.minMatchCharLength,
  82. keys: this.keys
  83. })
  84. },
  85. performSearch(value) {
  86. if(!value) {
  87. this.results = []
  88. return
  89. }
  90. if (this.mode === 'fuzzy') {
  91. this.results = this.fuse.search(value)
  92. } else {
  93. this.results = []
  94. for (let item of this.items) {
  95. for (let field in item) {
  96. if (typeof item[field] !== 'string') {
  97. continue
  98. }
  99. if (this.keys.length !== 0 && this.keys.indexOf(field) === -1) {
  100. continue
  101. }
  102. if (item[field].toLowerCase().indexOf(value.toLowerCase()) !== -1) {
  103. this.results.push(item)
  104. break
  105. }
  106. }
  107. }
  108. }
  109. }
  110. },
  111. data() {
  112. return {
  113. fuse: null,
  114. search: '',
  115. results: []
  116. }
  117. },
  118. mounted() {
  119. if (this.mode !== 'fuzzy') {
  120. return
  121. }
  122. this.initFuse()
  123. }
  124. }
  125. </script>
  126. <style lang="sass">
  127. .searcher
  128. text-align: center
  129. border-radius: 0 !important
  130. font:
  131. size: 11pt
  132. style: normal
  133. weight: bold
  134. </style>