v-model更改后如何触发功能?

时间:2016-10-19 23:55:25

标签: javascript vue.js

我有输入用于过滤Vue中的对象数组。我使用Salvattore构建了我过滤元素的网格,但它并没有很好地工作。我想我必须调用rescanMediaQueries();我的v模型改变之后的功能,但无法确定如何。

这是我的Vue实例:

var articlesVM = new Vue({
      el: '#search',
      data: {
        articles: [],
        searchInput: null
      },
      ready: function() {

          this.$http.get('posts').then(function (response) {
            this.articles = response.body;
          });

      }
});

以下是我构建搜索的方式

<div class="container" id="search">
  <div class="input-field col s6 m4">
    <input v-model="searchInput" class="center-align" id="searchInput" type="text" >
    <label class="center-align" for="searchInput"> search... </label>
  </div>

  <div id="search-grid" v-show="searchInput" data-columns>
    <article v-for="article in articles | filterBy searchInput">
        <div class="card">
            <div class="card-image" v-if="article.media" v-html="article.media"></div>
            <div class="card-content">
                <h2 class="card-title center-align">
                    <a v-bind:href="article.link">{{ article.title }}</a>
                   </h2>
                   <div class="card-excerpt" v-html="article.excerpt"></div>
            </div>
            <div class="card-action">
                <a v-bind:href="article.link"><?php _e('Read More', 'sage'); ?></a>
            </div>
        </div>
    </article>
  </div>

我确实通过在我的Vue中添加 watch 选项来使网格系统工作,但每次我在输入中写入内容然后删除它我的filterBy方法根本不起作用。即使我尝试重新键入与之前相同的关键字,它也没有填充任何数据。这是我使用的手表选项:

watch: {
   searchInput: function (){
       salvattore.rescanMediaQueries();
   }
}

1 个答案:

答案 0 :(得分:1)

我认为您的问题在于http成功处理程序中this的范围。 Vue组件中的articles对象未从http.get(..)成功处理程序获取任何值。

ready函数中,您的http成功处理程序应如下所示:

this.$http.get('posts').then(response => {
  this.articles = response.body;  // 'this' belongs to outside scope
});`

或者您也可以这样做:

var self = this;  // self points to 'this' of Vue component
this.$http.get('posts').then(response => {
  self.articles = response.body;  // 'self' points to 'this' of outside scope
});`

另一个类似问题:https://stackoverflow.com/a/40090728/654825

还有一件事 - 最好将数据定义为函数,如下所示:

var articlesVM = new Vue({
  el: '#search',
  data: function() {
    return {
      articles: [],
      searchInput: null
    }
  },
  ...
}

这可确保您的文章对象对于此组件实例是唯一的(当您在应用程序的多个位置使用相同的组件时)。

在评论#1

之后编辑

以下代码似乎正常,watch函数完美无缺:

var vm = new Vue({
    el: '#search',
    template: `<input v-model="searchInput" class="center-align" id="searchInput" type="text" >`,
    data: {
        searchInput: ""
    },
    watch: {
        searchInput: function() {
            console.log("searchInput changed to " + this.searchInput);
        }
    }
})

模板中的input是您的版本的精确副本 - 我甚至将idv-model一起设置,但我没有看到设置{{1}的原因}}

Vue.js版本:2.0.3

根据问题中的详细信息,我无法再看到任何内容。您能否检查一下您的代码是否与上面的代码匹配,看看是否可以获得控制台调试消息?

在评论#4,#5

之后编辑

这是您需要验证的另一个想法:

  • vue.js的角色:渲染DOM
  • salvattore插件的作用:仅使用CSS制作DOM布局

假设salvattore插件的上述情况属实,并且希望它不会与vue.js观察者/ getters / setter混淆,那么你可以执行以下操作:提供大约50 ms的时间延迟,以便vue.js完成渲染,然后调用salvattore插件来执行布局。

所以你的手表功能需要如下:

id

或者您也可以使用watch: { searchInput: function (){ setTimeout(function(){ salvattore.rescanMediaQueries(); }, 50); } } ,如下所示:

Vue.nexttick()

此处记录了Vue.nextTick(function () { // DOM updated }) https://vuejs.org/api/#Vue-nextTick

我不知道你是否需要为salvattore插件提供一些额外的时间来启动布局,但上面的一个应该可以解决。

让我知道它是否有效!