VueJS-按首字母过滤数据

时间:2019-07-16 16:11:09

标签: vue.js

我正在尝试使用输入字段和字母列表按名称过滤数据。文本输入字段过滤工作正常,但是,使用.startsWith()按字符串的第一个字母进行过滤是拒绝的。我对此还很陌生,无法解决。

我在做什么错?这是fiddle

<div id="app">
    <h1>Authors</h1>
    <div class="letters-list">
        <div class="letters-wrap" v-for="letter in letters" :key="letter">
            <div v-if="isAuthorLink(letter)" class="has-data">
                <input type="radio" :value="letter" v-model="lettersFilter">
                <label :for="letter">{{ letter }}</label>
            </div>
            <div v-else>{{ letter }}</div>
        </div>
    </div>
    <div class="search-wrapper">
        <input type="text" v-model="searchByName" placeholder="Search.." />
    </div>
    <div class="list-inner">
        <div v-for="author in authorsFilter" :key="author.id">
            <h5><a :href="author.link" v-html="author.name"></a></h5>
        </div>
    </div>
</div>

<script>
new Vue({
    el: '#app',

    data: function () {
        return {
        authors: [
    {
        "id": 77,
        "link": "http://my-site/authors/anonymous/",
        "name": "Anonymous",
        "slug": "anonymous"
    },
    {
        "id": 72,
        "link": "http://my-site/authors/ferdinand-marcos/",
        "name": "Ferdinand Marcos",
        "slug": "ferdinand-marcos"
    },
    {
        "id": 75,
        "link": "http://my-site/authors/john-f-kennedy/",
        "name": "John F. Kennedy",
        "slug": "john-f-kennedy"
    },
    {
        "id": 67,
        "link": "http://my-site/authors/john-maxwell/",
        "name": "John Maxwell",
        "slug": "john-maxwell"
    }
],
        searchByName: '',
        lettersFilter: ''
      }
    },
    computed: {
        letters() {
            let letters = []
            for(let i = "A".charCodeAt(0); i <= "Z".charCodeAt(0); i++) {letters.push(String.fromCharCode([i]))}
            return letters
        },
        authorsFilter() {
            if(this.searchByName){
                return this.authors.filter((item)=>{
                    return item.name.toLowerCase().includes(this.searchByName.toLowerCase())
                })
            } if(this.lettersFilter){
                return this.authors.filter((item)=>{
                    return item.name.toLowerCase().startsWith(this.lettersFilter.toLowerCase());
                })
            } else {
                return this.authors;
            }
        },
    },
    methods: {
        isAuthorLink(letter) {
            return this.authors.some(aut => aut.name.startsWith(letter))
        },
    }
})
</script>

2 个答案:

答案 0 :(得分:1)

您需要在id的输入元素上具有label属性才能与之关联;没有一个事件,@input事件将不会发出,并且value也不会更新。

<div v-if="isAuthorLink(letter)" class="has-data">
  <input :id="letter" type="radio" :value="letter" v-model="lettersFilter">
  <label :for="letter">{{ letter }}</label>
</div>

<label>的{​​{3}}上引用文档:

  

id元素在同一文档中的可标记表单相关元素的<label>。文档中具有id匹配for属性值的第一个元素是此label元素的 labeled控件(如果它是可标记的元素)。如果它不可标记,则for属性无效。如果还有其他元素也与id值匹配,则在文档的后面,将不考虑它们。

答案 1 :(得分:1)

Yom S。是正确的,主要问题是您的<label><input>没有关联。 <input>本身被CSS隐藏,因此只有<label>是可单击的。永远不会触发过滤。

使用for / id的另一种方法是将<input>放在<label>内。

<label>{{ letter }}<input type="radio" :value="letter" v-model="lettersFilter"></label>

这将在<input><label>之间创建一个隐式链接,因此单击<label>就相当于单击<input>

在不相关的注释上,如果可以帮助,我建议不要使用v-html