计算数据更改时,Vue不会更新(Vue doesn't update when computed data change)

编程入门 行业动态 更新时间:2024-10-18 23:22:26
计算数据更改时,Vue不会更新(Vue doesn't update when computed data change)

上下文:我有一个带有标签的帖子列表,来自wordpress api的类别。 我用Vue显示这些帖子,并使用computed与搜索框根据滴定,描述,标记和类别过滤结果

问题:我正尝试在用户点击可用标签列表时更新computed列表。 我为这样的computed数据添加get和set :

var vm = new Vue({
    el: '#blogs',       
    data: {
        search: '',
        posts: [],
        filterPosts: []
    },
    beforeMount: function() {
        // It should call the data and update
        callData();
    },
    computed: {
        filterPosts: {
            get: function() {
                var self = this;
                return self.posts.filter(function(post){
                    var query = self.search.toLowerCase();
                    var title = post.title.toLowerCase();
                    var content = post.content.toLowerCase();
                    var date = post.date.toLowerCase();
                    var categories = '';
                    post.categories.forEach(function(category) {
                       categories += category.name.toLowerCase(); 
                    });
                    var tags = '';
                    post.tags.forEach(function(tag){
                        tags += tag.name.toLowerCase();
                    });
                    return title.indexOf(query) !== -1 ||content.indexOf(query) !== -1 || date.indexOf(query) !== -1 || categories.indexOf(query) !== -1 || tags.indexOf(query) !== -1;
                });
            },
            set: function (newValue) {
                console.log(newValue);
                this.filterPosts = Object.assign({}, newValue);
            }
        }
    },
    methods: {
        filterByTag: function(tag, event) {
            event.preventDefault();
            var self = this;
            self.filterPosts = self.posts.filter(function(post){
                var tags = '';
                post.tags.forEach(function(tag){
                    tags += tag.name.toLowerCase();
                });
                return tags.indexOf(tag.toLowerCase()) !== -1;
            });
        }
    }
}); // Vue instance 
  
 

console.log总是根据我在methods上写的函数输出新的数据,但Vue没有重新渲染视图。 我认为我没有做正确的方式,或者像Vue一样思考。 你能否提供一些见解?

编辑1添加完整代码。

我试图在data添加filterPosts但是我从Vue收到了这个错误: The computed property "filterPosts" is already defined in data.

Context: I have a list of posts with tags, categories from wordpress api. I display these posts with Vue and using computed with a search box to filter the result based on titre, description, tags, and categories

Problem: I am trying to update a computed list when user click on a list of tag available. I add the get and set for computed data like this:

var vm = new Vue({
    el: '#blogs',       
    data: {
        search: '',
        posts: [],
        filterPosts: []
    },
    beforeMount: function() {
        // It should call the data and update
        callData();
    },
    computed: {
        filterPosts: {
            get: function() {
                var self = this;
                return self.posts.filter(function(post){
                    var query = self.search.toLowerCase();
                    var title = post.title.toLowerCase();
                    var content = post.content.toLowerCase();
                    var date = post.date.toLowerCase();
                    var categories = '';
                    post.categories.forEach(function(category) {
                       categories += category.name.toLowerCase(); 
                    });
                    var tags = '';
                    post.tags.forEach(function(tag){
                        tags += tag.name.toLowerCase();
                    });
                    return title.indexOf(query) !== -1 ||content.indexOf(query) !== -1 || date.indexOf(query) !== -1 || categories.indexOf(query) !== -1 || tags.indexOf(query) !== -1;
                });
            },
            set: function (newValue) {
                console.log(newValue);
                this.filterPosts = Object.assign({}, newValue);
            }
        }
    },
    methods: {
        filterByTag: function(tag, event) {
            event.preventDefault();
            var self = this;
            self.filterPosts = self.posts.filter(function(post){
                var tags = '';
                post.tags.forEach(function(tag){
                    tags += tag.name.toLowerCase();
                });
                return tags.indexOf(tag.toLowerCase()) !== -1;
            });
        }
    }
}); // Vue instance 
  
 

The console.log always output new data based on the function I wrote on methods but Vue didn't re-render the view. I think I didn't do the right way or thought like Vue. Could you please give some insight?

Edit 1 Add full code.

I tried to add filterPosts in data but I received this error from Vue: The computed property "filterPosts" is already defined in data.

最满意答案

你的setter实际上没有设置任何东西,它只记录新的值。 你需要将它存储在某个地方。

例如,您可以将其存储在组件的数据中:

data: { value: 'foo', }, computed: { otherValue: { get() { /*...*/ }, set(newVal) { this.value = newVal }, }, },

但是,这绝对不是唯一的可能性,如果你使用Vuex,setter可以派发一个动作,然后使计算的值得到更新。 该组件最终将捕获更新并显示新值。

computed: { value: { get() { return this.$store.getters.externalData; }, set(newVal) { return this.$store.dispatch('modifyingAction', newVal); }, }, },

底线是你必须触发setter中的数据更改,否则你的组件将不会更新,也不会触发任何重新渲染。


编辑(原始答案更新完整代码):

答案是,除非您想手动更改列表filteredPosts而不更改posts ,否则您不需要计算变量的get和set函数。 您想要的行为可以通过以下方式实现:

const vm = new Vue({ data() { return { search: '', posts: [], // these should probably be props, or you won't be able to edit the list easily. The result is the same anyway. }; }, computed: { filteredPosts() { return this.posts.filter(function(post) { ... // do the filtering }); }, }, template: "<ul><li v-for='post in filteredPosts'>{{ post.content }}</li></ul>", });

这样,如果您更改数据中的posts或search变量, filteredPosts将得到重新计算,并且重新呈现将被触发。

After going around and around, I found a solution, I think it may be the right way with Vue now: Update the computed data through its dependencies properties or data.

The set method didn't work for this case so I add an activeTag in data, when I click on a tag, it will change the activeTag and notify the computed filterPost recheck and re-render. Please tell me if we have another way to update the computed data.

var vm = new Vue({
    el: '#blogs',       
    data: {
        search: '',
        posts: [],
        tags: [],
        activeTag: ''
    },
    beforeMount: function() {
        // It should call the data and update
        callData();
    },
    computed: {
        filterPosts: {
            get: function() {
                var self = this;
                return self.posts.filter(function(post){
                    var query = self.search.toLowerCase();
                    var title = post.title.toLowerCase();
                    var content = post.content.toLowerCase();
                    var date = post.date.toLowerCase();
                    var categories = '';
                    post.categories.forEach(function(category) {
                       categories += category.name.toLowerCase(); 
                    });
                    var tags = '';
                    post.tags.forEach(function(tag){
                        tags += tag.name.toLowerCase();
                    });
                    var activeTag = self.activeTag;
                    if (activeTag !== '') {
                        return tags.indexOf(activeTag.toLowerCase()) !== -1;
                    }else{
                        return title.indexOf(query) !== -1 ||content.indexOf(query) !== -1 || date.indexOf(query) !== -1 || categories.indexOf(query) !== -1 || tags.indexOf(query) !== -1;
                    }                       
                });
            },
            set: function (newValue) {
                console.log(newValue);
            }
        }
    },
    methods: {
        filterByTag: function(tag, event) {
            event.preventDefault();
            var self = this;
            self.activeTag = tag;
        }
    }
}); // Vue instance 
  
 

更多推荐

本文发布于:2023-07-26 00:29:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1268433.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数据   Vue   update   change   data

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!