比较精妙的设计是:对于搜索排序函数,传入了一个 fun 函数作为参数,这使得对于列表中的元素可以灵活处理。
运行试试:
<link rel="stylesheet" type="text/css" href="https://cdn.uv.cc/layui/2.9.14/css/layui.css" /> <script src="https://cdn.uv.cc/layui/2.9.14/layui.js"></script> <style> .input-wrapper { position: relative; margin: 5px; } .clear-icon { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); cursor: pointer; font-size: 18px; } </style> <div id="app"> <div class="input-wrapper"> <input v-model="search_word" type="text" id="username" class="layui-input" placeholder="搜索,支持空格分词"> <i @click="search_word = ''" v-show="search_word !== ''" class="layui-icon clear-icon" id="clearIcon">ဆ</i> <!-- 清空图标 --> </div> <div style="margin: 5px;" v-for="item of filter_sort(li, search_word, function(x) {return x})"> {{item}} </div> </div> <script src="https://cdn.uv.cc/vue/2.6.10/vue.min.js"></script> <script> new Vue({ el: '#app', data: { search_word: '', li: [ '天王盖地虎', '风萧萧兮易水寒', '独在异乡为异客', '二月春风似剪刀', ], }, methods: { filter_sort(data, search, fun) { if(search.trim() === '') { return data } // 空格分词 let a = search.split(' ') // 选择有效词 let b = [] for(let item of a) { item = item.trim() if(item !== '') { b.push(item) } } let len = b.length // 打分以排序 let new_data = [] for(item of data) { let score = 0 // 第几号位置的检索词 let p = len for(let ib of b) { if(fun(item).toUpperCase().indexOf(ib.toUpperCase()) !== -1) { score += 2 * len + p } p -= 1 } if(score > 0) { new_data.push({ score: score, item: item, }) } } // 对 new_data 进行排序 new_data.sort(function(x, y) { return y.score - x.score }) let return_data = [] for(item of new_data) { return_data.push(item.item) } return return_data }, }, }) </script>