v-model改变后如何触发功能? [英] How to fire function after v-model change?

查看:127
本文介绍了v-model改变后如何触发功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有输入用于过滤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 =containerid =search> 
< div class =input-field col s6 m4>
< input v-model =searchInputclass =center-alignid =searchInputtype =text>
< label class =center-alignfor =searchInput>搜索...< / label>
< / div>

< div id =search-gridv-show =searchInputdata-columns>
< article v-for =文章中的文章| filterBy searchInput>
< div class =card>
< div class =card-imagev-if =article.mediav-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-excerptv-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();
}
}


解决方案

我认为你的问题是你的成功处理程序中的这个的范围。 Vue组件中的文章对象未从 http.get(..)成功处理程序中获取任何值。 / p>

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

 这。$ http.get('posts')。then(response => {
this.articles = response.body; //'this '属于外部范围
});`

或者您也可以这样做:

  var self = this; //自我指向Vue组件的'this'
this。$ http.get('posts')。then(response => {
self.articles = response.body; //'self '指向'这个'的外部范围
});`

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



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

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

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



在评论#1后编辑



以下代码似乎没问题,监视功能完美无缺:

  var vm = new Vue({
el:'#search',
template:`< input v-model =searchInputclass =center-alignid =searchInputtype =text>`,
data:{
searchInput:
},
watch:{
searchInput:function(){
console.log(searchInput更改为+ this.searchInput;
}
}
})

<$ c $模板中的c> input 是您的版本的精确副本 - 我甚至设置了 id 以及 v-model ,虽然我没有看到设置 id的原因



Vue.js版本:2.0.3



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



在评论#4,#5之后编辑



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




  • 角色of vue.js:渲染DOM

  • salvattore插件的角色:仅使用CSS制作DOM布局



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



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

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

或者您也可以使用 Vue.nexttick()如下:

  Vue.nextTick(function(){
// DOM更新
})

nextTick https://vuejs.org/api/#Vue-nextTick



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



让我知道它是否有效!


I have input which I use to filter my array of objects in Vue. I'm using Salvattore to build a grid of my filtered elements, but it doesn't work too well. I think I have to call rescanMediaQueries(); function after my v-model changes but can't figure how.

Here is my Vue instance:

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

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

      }
});

And here is how I have built my search

<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>

I did get the grid system working by adding watch option to my Vue, but every time I wrote something to my input and then erase it my filterBy method wouldn't work at all. It didn't populate any data even if I tried to retype the same keyword as earlier. Here is the watch option I used:

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

解决方案

I think your problem is with the scoping of this in your success handler for http. Your articles object in Vue component is not getting any values from your http.get(..) success handler.

Inside your ready function, your http success handler should be as follows:

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

Alternatively you can also do:

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
});`

Another similar issue: https://stackoverflow.com/a/40090728/654825

One more thing - it is preferable to define data as a function, as follows:

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

This ensures that your articles object is unique to this instance of the component (when you use the same component at multiple places within your app).

Edited after comment #1

The following code seems to work alright, the watch function works flawlessly:

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);
        }
    }
})

The input in template is an exact copy of your version - I have even set the id along with v-model, though I do not see the reason to set an id

Vue.js version: 2.0.3

I am unable to see any further, based on details in the question. Can you check if your code matches with the one above and see if you can get the console debugging messages?

Edited after comment #4, #5

Here is another thought which you need to verify:

  • Role of vue.js: Render the DOM
  • Role of salvattore plugin: Make the DOM layouts using CSS only

Assuming the above is true for salvattore plugin, and hopefully it does not mess with vue.js observers / getters / setters, then you can do the following: provide a time delay of about 50 ms so that vue.js completes the rendering, and then call the salvattore plugin to perform the layouts.

So your watch function needs to be as follows:

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

Alternatively you may also use Vue.nexttick() as follows:

Vue.nextTick(function () {
    // DOM updated
})

The nextTick is documented here: https://vuejs.org/api/#Vue-nextTick

I do not know if you may need to provide a little bit of extra time for salvattore plugin to start the layouts, but one of the above should work out.

Let me know if it works!

这篇关于v-model改变后如何触发功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆