【问题标题】:Vue custom filtering input componentVue自定义过滤输入组件
【发布时间】:2017-11-22 23:44:55
【问题描述】:

我正在尝试创建一个“只有”文本输入的组件。在此输入中键入的字符串将用于过滤列表。我的问题是我无法处理如何在我的组件和包含要过滤的列表的主应用程序之间共享此过滤器字符串。

我尝试了几件事,但大多数时候我得到了错误: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value

所以我查看了 Vuex,但我认为在这种情况下它无济于事,因为我可以在同一页面中为不同的列表使用多个过滤器组件,并且我不希望它们同步 ^^

这是我所拥有的:

过滤器组件

<script type="x/template" id="filterTpl">
    <div> 
        <span class="filter-wrapper">
            <input type="search" class="input input-filter" v-model.trim="filter" />
        </span>
    </div>
</script>

<script>
    Vue.component('list-filter', {
        props: {
            filter: String
        }
        template: '#filterTpl'
    });
</script>

还有我的主应用:

<div id="contacts">
        <list-filter :filter="filter"></list-filter>
        <ul class="contacts-list managed-list flex">
            <li class="contact" v-for="contactGroup in filteredData">
                [...]
            </li>
        </ul>
    </div>

<script>
    var contactsV = new Vue({
        el: '#contacts',
        data: {
            filter: "",
            studyContactsGroups: []
        },
        computed: {
            filteredData: function(){
                // Using this.filter to filter the studyContactsGroups data
                [...]
                return filteredContacts;
            }
        }
    });
</script>

感谢任何帮助或提示:)

【问题讨论】:

  • 您可以在输入组件上使用 syncfilter 属性:vuejs.org/v2/guide/components.html#sync-Modifier - 这将更新父组件内的过滤器属性。您需要重构输入组件以定义 value 属性并发出新值:this.$emit('update:filter', newFilter)
  • 嗨!谢谢。我偶然发现了这个文档,但我无法让它工作。所以我必须像这样同步组件的道具: 然后在组件中创建另一个名为 value 的道具,当输入更改时,触发过滤器道具父级的更新?
  • 那么我必须将发出 prop 更改的方法放在哪里?

标签: vue.js vue-component


【解决方案1】:

您可以通过显式 prop-event 连接或更简洁的 v-bindsync 修饰符同步子值和父 prop:

new Vue({
  el: '#app',
  data: {
    rawData: ['John', 'Jane', 'Jim', 'Eddy', 'Maggy', 'Trump', 'Che'],
    filter: ''
  },
  components: {
    'my-input' : {
      // bind prop 'query' to value and
      // @input update parent prop 'filter' via event used with '.sync'
      template: `<input :value="query" @input="updateFilter">`,
      props: ['query'],
      methods: {
      	updateFilter: function(e) {
          this.$emit('update:query', e.target.value) // this is described in documentation
        }
      }
    }
  },
  computed: {
    filteredData: function() {
      // simple filter function
      return this.rawData.filter(el => el.toLowerCase()
      	.match(this.filter.toLowerCase()))
    }
  }
});
<script src="https://unpkg.com/vue/dist/vue.js"></script>

<div id="app">
  <my-input :query.sync="filter"></my-input>
  <hr>
  <ul>
    <li v-for="line in filteredData">{{ line }}</li>
  </ul>
</div>

【讨论】:

    猜你喜欢
    • 2015-12-14
    • 2021-02-09
    • 2020-06-09
    • 2015-07-18
    • 1970-01-01
    • 2017-06-06
    • 2018-10-03
    • 2021-06-25
    • 2021-07-26
    相关资源
    最近更新 更多