Computed properties on Vuex state array objects
This question may also be applicable to Vue in general, but I am using Vuex for my project.
I have an array of objects in my store for which I would like to have a calculated property.
To simplify, assume my store is as follows:
const state = {
numbers = [
{num: 2, multiplier: 3},
{num: 5, multiplier: 10},
{num: 1, multiplier: 6}
]
};
Now, I want a calculated property on each object of the numbers array, such that the result is num * multiplier (eg. 2*3 = 6, 5*10 = 50)
One solution is to make a calculated property that returns the numbers array, plus the calculated field... eg:
const getterrs = {
num_list(state){
const list = state.numbers
list.map(n=>{
n.value=n.num*n.multiplier;
);
return list;
}
}
That works, but it has a couple issues:
The array returned cannot be bound with v-model on the non-computed
fieldsThe entire array will be recalculated whenever any element in the
array is changed... I only want to recalculate the individual element
that changed.
Is that possible with Vue/Vuex?
vue.js vuejs2 vuex
add a comment |
This question may also be applicable to Vue in general, but I am using Vuex for my project.
I have an array of objects in my store for which I would like to have a calculated property.
To simplify, assume my store is as follows:
const state = {
numbers = [
{num: 2, multiplier: 3},
{num: 5, multiplier: 10},
{num: 1, multiplier: 6}
]
};
Now, I want a calculated property on each object of the numbers array, such that the result is num * multiplier (eg. 2*3 = 6, 5*10 = 50)
One solution is to make a calculated property that returns the numbers array, plus the calculated field... eg:
const getterrs = {
num_list(state){
const list = state.numbers
list.map(n=>{
n.value=n.num*n.multiplier;
);
return list;
}
}
That works, but it has a couple issues:
The array returned cannot be bound with v-model on the non-computed
fieldsThe entire array will be recalculated whenever any element in the
array is changed... I only want to recalculate the individual element
that changed.
Is that possible with Vue/Vuex?
vue.js vuejs2 vuex
add a comment |
This question may also be applicable to Vue in general, but I am using Vuex for my project.
I have an array of objects in my store for which I would like to have a calculated property.
To simplify, assume my store is as follows:
const state = {
numbers = [
{num: 2, multiplier: 3},
{num: 5, multiplier: 10},
{num: 1, multiplier: 6}
]
};
Now, I want a calculated property on each object of the numbers array, such that the result is num * multiplier (eg. 2*3 = 6, 5*10 = 50)
One solution is to make a calculated property that returns the numbers array, plus the calculated field... eg:
const getterrs = {
num_list(state){
const list = state.numbers
list.map(n=>{
n.value=n.num*n.multiplier;
);
return list;
}
}
That works, but it has a couple issues:
The array returned cannot be bound with v-model on the non-computed
fieldsThe entire array will be recalculated whenever any element in the
array is changed... I only want to recalculate the individual element
that changed.
Is that possible with Vue/Vuex?
vue.js vuejs2 vuex
This question may also be applicable to Vue in general, but I am using Vuex for my project.
I have an array of objects in my store for which I would like to have a calculated property.
To simplify, assume my store is as follows:
const state = {
numbers = [
{num: 2, multiplier: 3},
{num: 5, multiplier: 10},
{num: 1, multiplier: 6}
]
};
Now, I want a calculated property on each object of the numbers array, such that the result is num * multiplier (eg. 2*3 = 6, 5*10 = 50)
One solution is to make a calculated property that returns the numbers array, plus the calculated field... eg:
const getterrs = {
num_list(state){
const list = state.numbers
list.map(n=>{
n.value=n.num*n.multiplier;
);
return list;
}
}
That works, but it has a couple issues:
The array returned cannot be bound with v-model on the non-computed
fieldsThe entire array will be recalculated whenever any element in the
array is changed... I only want to recalculate the individual element
that changed.
Is that possible with Vue/Vuex?
vue.js vuejs2 vuex
vue.js vuejs2 vuex
asked Nov 21 '18 at 0:20
corycorycorycorycorycory
297415
297415
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
You could do any computing of your store data in the component it is being used in. I would have your getter simply return the numbers array:
const getters = {
num_list(state){
return state.numbers;
}
}
Then in your component you can access numbers with the getter and use it how you want. So if you want to display the original array you could get it like this:
computed: {
num_list() {
return this.$store.getters.num_list
}
}
and display it in your template like this:
<p>Our first number is {{num_list[0].num}} and it's multiplier is {{num_list[0].num}}</p>
If you want to have the multiplication calculated as well you can have another computed property:
multiplied() {
return this.num_list[0].num*this.num_list[0].multiplier
}
and echo it in the template with {{multiplied}}
.
Now it would make things a bit more flexible if you had a data element in your component that could be used as the index, or if you had a method instead of a computed property so you could pass a parameter. (You shouldn't pass parameters to computed property as I understand it). So your method of multiplied would be this:
multipliedMethod(index) {
return this.num_list[index].num*this.num_list[index].multiplier
}
Or if you want to show all the results you can iterate through your num_list with v-for and do any calculation on the fly:
<div v-for="(num, index) in num_list" :key="index">
<p>{{num.num*num.multiplier}}</p>
</div>
That works fine for a single component, but one of the benefits of Vuex is managing a global state across multiple components. You would have to implement that computed property in every component you need to use it in. I was hoping for some kind of solution that doesn't violate the DRY principle :)
– corycorycory
Nov 21 '18 at 3:02
So you need an action and/or a mutation. An action is a global method, and can be called from anywhere. So the example method in my answer could be made into an action in your store. If you want to actually change your state then you need a mutation. If you want answers to your last two points you might need to include a use case in your question.
– Andrew1325
Nov 21 '18 at 4:02
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53403573%2fcomputed-properties-on-vuex-state-array-objects%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You could do any computing of your store data in the component it is being used in. I would have your getter simply return the numbers array:
const getters = {
num_list(state){
return state.numbers;
}
}
Then in your component you can access numbers with the getter and use it how you want. So if you want to display the original array you could get it like this:
computed: {
num_list() {
return this.$store.getters.num_list
}
}
and display it in your template like this:
<p>Our first number is {{num_list[0].num}} and it's multiplier is {{num_list[0].num}}</p>
If you want to have the multiplication calculated as well you can have another computed property:
multiplied() {
return this.num_list[0].num*this.num_list[0].multiplier
}
and echo it in the template with {{multiplied}}
.
Now it would make things a bit more flexible if you had a data element in your component that could be used as the index, or if you had a method instead of a computed property so you could pass a parameter. (You shouldn't pass parameters to computed property as I understand it). So your method of multiplied would be this:
multipliedMethod(index) {
return this.num_list[index].num*this.num_list[index].multiplier
}
Or if you want to show all the results you can iterate through your num_list with v-for and do any calculation on the fly:
<div v-for="(num, index) in num_list" :key="index">
<p>{{num.num*num.multiplier}}</p>
</div>
That works fine for a single component, but one of the benefits of Vuex is managing a global state across multiple components. You would have to implement that computed property in every component you need to use it in. I was hoping for some kind of solution that doesn't violate the DRY principle :)
– corycorycory
Nov 21 '18 at 3:02
So you need an action and/or a mutation. An action is a global method, and can be called from anywhere. So the example method in my answer could be made into an action in your store. If you want to actually change your state then you need a mutation. If you want answers to your last two points you might need to include a use case in your question.
– Andrew1325
Nov 21 '18 at 4:02
add a comment |
You could do any computing of your store data in the component it is being used in. I would have your getter simply return the numbers array:
const getters = {
num_list(state){
return state.numbers;
}
}
Then in your component you can access numbers with the getter and use it how you want. So if you want to display the original array you could get it like this:
computed: {
num_list() {
return this.$store.getters.num_list
}
}
and display it in your template like this:
<p>Our first number is {{num_list[0].num}} and it's multiplier is {{num_list[0].num}}</p>
If you want to have the multiplication calculated as well you can have another computed property:
multiplied() {
return this.num_list[0].num*this.num_list[0].multiplier
}
and echo it in the template with {{multiplied}}
.
Now it would make things a bit more flexible if you had a data element in your component that could be used as the index, or if you had a method instead of a computed property so you could pass a parameter. (You shouldn't pass parameters to computed property as I understand it). So your method of multiplied would be this:
multipliedMethod(index) {
return this.num_list[index].num*this.num_list[index].multiplier
}
Or if you want to show all the results you can iterate through your num_list with v-for and do any calculation on the fly:
<div v-for="(num, index) in num_list" :key="index">
<p>{{num.num*num.multiplier}}</p>
</div>
That works fine for a single component, but one of the benefits of Vuex is managing a global state across multiple components. You would have to implement that computed property in every component you need to use it in. I was hoping for some kind of solution that doesn't violate the DRY principle :)
– corycorycory
Nov 21 '18 at 3:02
So you need an action and/or a mutation. An action is a global method, and can be called from anywhere. So the example method in my answer could be made into an action in your store. If you want to actually change your state then you need a mutation. If you want answers to your last two points you might need to include a use case in your question.
– Andrew1325
Nov 21 '18 at 4:02
add a comment |
You could do any computing of your store data in the component it is being used in. I would have your getter simply return the numbers array:
const getters = {
num_list(state){
return state.numbers;
}
}
Then in your component you can access numbers with the getter and use it how you want. So if you want to display the original array you could get it like this:
computed: {
num_list() {
return this.$store.getters.num_list
}
}
and display it in your template like this:
<p>Our first number is {{num_list[0].num}} and it's multiplier is {{num_list[0].num}}</p>
If you want to have the multiplication calculated as well you can have another computed property:
multiplied() {
return this.num_list[0].num*this.num_list[0].multiplier
}
and echo it in the template with {{multiplied}}
.
Now it would make things a bit more flexible if you had a data element in your component that could be used as the index, or if you had a method instead of a computed property so you could pass a parameter. (You shouldn't pass parameters to computed property as I understand it). So your method of multiplied would be this:
multipliedMethod(index) {
return this.num_list[index].num*this.num_list[index].multiplier
}
Or if you want to show all the results you can iterate through your num_list with v-for and do any calculation on the fly:
<div v-for="(num, index) in num_list" :key="index">
<p>{{num.num*num.multiplier}}</p>
</div>
You could do any computing of your store data in the component it is being used in. I would have your getter simply return the numbers array:
const getters = {
num_list(state){
return state.numbers;
}
}
Then in your component you can access numbers with the getter and use it how you want. So if you want to display the original array you could get it like this:
computed: {
num_list() {
return this.$store.getters.num_list
}
}
and display it in your template like this:
<p>Our first number is {{num_list[0].num}} and it's multiplier is {{num_list[0].num}}</p>
If you want to have the multiplication calculated as well you can have another computed property:
multiplied() {
return this.num_list[0].num*this.num_list[0].multiplier
}
and echo it in the template with {{multiplied}}
.
Now it would make things a bit more flexible if you had a data element in your component that could be used as the index, or if you had a method instead of a computed property so you could pass a parameter. (You shouldn't pass parameters to computed property as I understand it). So your method of multiplied would be this:
multipliedMethod(index) {
return this.num_list[index].num*this.num_list[index].multiplier
}
Or if you want to show all the results you can iterate through your num_list with v-for and do any calculation on the fly:
<div v-for="(num, index) in num_list" :key="index">
<p>{{num.num*num.multiplier}}</p>
</div>
answered Nov 21 '18 at 2:50
Andrew1325Andrew1325
41829
41829
That works fine for a single component, but one of the benefits of Vuex is managing a global state across multiple components. You would have to implement that computed property in every component you need to use it in. I was hoping for some kind of solution that doesn't violate the DRY principle :)
– corycorycory
Nov 21 '18 at 3:02
So you need an action and/or a mutation. An action is a global method, and can be called from anywhere. So the example method in my answer could be made into an action in your store. If you want to actually change your state then you need a mutation. If you want answers to your last two points you might need to include a use case in your question.
– Andrew1325
Nov 21 '18 at 4:02
add a comment |
That works fine for a single component, but one of the benefits of Vuex is managing a global state across multiple components. You would have to implement that computed property in every component you need to use it in. I was hoping for some kind of solution that doesn't violate the DRY principle :)
– corycorycory
Nov 21 '18 at 3:02
So you need an action and/or a mutation. An action is a global method, and can be called from anywhere. So the example method in my answer could be made into an action in your store. If you want to actually change your state then you need a mutation. If you want answers to your last two points you might need to include a use case in your question.
– Andrew1325
Nov 21 '18 at 4:02
That works fine for a single component, but one of the benefits of Vuex is managing a global state across multiple components. You would have to implement that computed property in every component you need to use it in. I was hoping for some kind of solution that doesn't violate the DRY principle :)
– corycorycory
Nov 21 '18 at 3:02
That works fine for a single component, but one of the benefits of Vuex is managing a global state across multiple components. You would have to implement that computed property in every component you need to use it in. I was hoping for some kind of solution that doesn't violate the DRY principle :)
– corycorycory
Nov 21 '18 at 3:02
So you need an action and/or a mutation. An action is a global method, and can be called from anywhere. So the example method in my answer could be made into an action in your store. If you want to actually change your state then you need a mutation. If you want answers to your last two points you might need to include a use case in your question.
– Andrew1325
Nov 21 '18 at 4:02
So you need an action and/or a mutation. An action is a global method, and can be called from anywhere. So the example method in my answer could be made into an action in your store. If you want to actually change your state then you need a mutation. If you want answers to your last two points you might need to include a use case in your question.
– Andrew1325
Nov 21 '18 at 4:02
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53403573%2fcomputed-properties-on-vuex-state-array-objects%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown