Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue Component, assign computed property to data

i'm trying to set a component's data to a computed property value, as this fetches some localStorage data and manipulates it slightly.

I would then once the component is mounted listen for changes within the localStorage, and if my key is updated then fetch this value again, run it through my computed property and pass it back to the view.

However i'm getting the following error:

ReferenceError: ids is not defined
    at a.render (vue.js:4)
    at a.e._render (vue:6)
    at a.r (vue:6)
    at un.get (vue:6)
    at new un (vue:6)
    at vue:6
    at a.bn.$mount (vue:6)
    at a.bn.$mount (vue:6)
    at init (vue:6)
    at vue:6

This is my component:

Vue.component('favourites-button', {
    render() {
        return this.$scopedSlots.default({
            count: this.ids.length
        });
    },
    data: function() {
        return {
            ids: this.getFavourites()
        }
    },
    mounted() {
        const self = this;
        Event.listen('favourites-updated', function (event) {
            console.log('updated external');
        });
        window.addEventListener('storage', function (e) {
            if (e.key === 'favourites') {
                console.log('updated');
                self.ids = self.getFavourites();
            }
        });
    },
    methods: {
        getFavourites: function() {
            let favourites = localStorage.getItem('favourites');
            return favourites.split(',').filter(id => !!id);
        }
    }
});

Edit:

Updated my code, getting the same error however when the storage change event is fired.

Edit 2:

Turns out my template was expecting toggle within my scope but I removed this from my $scopedSlots.

like image 680
Martyn Ball Avatar asked Oct 14 '25 07:10

Martyn Ball


2 Answers

You can use computed properties for this, but you'd have to define a getter and a setter.

computed: {
  fullName: {
    // getter
    get: function () {
      return localStorage.getItem('favourites')
    },
    // setter
    set: function (newValue) {
      localStorage.setItem('favourites', newValue)
    }
  }
}

Much cleaner imo than using the mounted callback, setting data and then watching for changes.

like image 121
Erik Terwan Avatar answered Oct 17 '25 02:10

Erik Terwan


Computed properties work on data/props, so you can’t use them in data itself.

Instead, just set the default value of the data key to what’s in local storage:

data: function () {
    return {
        ids: function() {
            let favourites = localStorage.getItem('favourites');
            return favourites.split(',').filter(id => !!id);
        }
    };
}
like image 31
Martin Bean Avatar answered Oct 17 '25 02:10

Martin Bean



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!