use $on() inside computed: {} in vue.js - vuejs2

I am trying to use checked values of HTML checkboxes in another component like below but I am not getting any output.
computed: {
formated () {
EventBus.$on('change', function (checkedSkills) {
console.log(checkedSkills)
});
}
},
Thanks
UPDATE
Now I am trying to do like below
data() {
return {
values: [],
}
},
computed: {
formated () {
console.log(this.values)
}
},
created () {
EventBus.$on('change', function (skillName) {
this.values = skillName
});
},

I think you are misunderstanding what the computed object is for. computed is so that you can create what are essentially variables using other bits of data or logic.
Your new computed value formated (BTW, it's "formatted" with two t's) is actually a method, not a variable.
You should simply change computed to methods if you want to log something to the console.
Here is a section in the Vue docs about the differences between computed and methods: https://v2.vuejs.org/v2/guide/computed.html#Computed-Caching-vs-Methods
So instead of what you have now:
computed: {
formated () {
console.log(this.values)
}
},
You should simply have:
methods: {
formated () {
console.log(this.values)
}
},

Related

How to have an if/else statement in a computed/methods property block for VueX?

I have a variable passed into a component called "store". This will store the name of the store that needs to be used in the component. This component just needs to make sure to get the data from the proper store.
computed: {
if (this.store === "storeNumber1")
...mapGetters(this.store, ["thing1", "thing2"]),
else if(this.store === "storeNumber2")
...mapGetters(this.store, ["thing1", "thing2"]),
}
props: {
store
}
This does not work. What would I need to make this concept work? And what about for Vue Mutations? Thank you.
mapGetters isn't meant to be used in a reactive way based on a prop.
Instead, you should use the longhand syntax to access the namespaced getter from the this.$store.getters object:
this.$store.getters[__MODULE_NAME__ + '/' + __GETTER_NAME]
Use that syntax in a computed property for each getter:
export default {
props: {
store: {
type: String,
required: true,
},
},
computed: {
thing1() {
return this.$store.getters[this.store + '/thing1']
},
thing2() {
return this.$store.getters[this.store + '/thing2']
},
},
}
demo
Yes, this does not work. computed properties need to be functions with a simple return. What you want need to be compined between computed and methods:
methods: {
myFunction() {
if (this.store === "storeNumber1") {
return ...mapGetters(this.store, ["thing1", "thing2"])
}
else if(this.store === "storeNumber2") {
return ...mapGetters(this.store, ["thing1", "thing2"])
}
}
}
computed: {
myComputedProperty() {
return this.myFunction()
}
}
props: {
store
}

Why does Vue not recognise the data member used in the v-html property?

I have a reusable Vue component as follows:
Vue.component('ValueDisplay', {
template: '<div v-html="value"></div>',
data: function () {
value: ''
},
mounted: function() {
this.$el.client = this;
},
methods: {
SetValue: function(value) {
this.value = value;
},
}
});
It is intended to be used as follows:
<value-display id="battery_percent">
Code that processes data from a web socket then calls the following function to set the value.
window.SetValue = function(name, value)
{
var el = document.getElementById(name);
if ((null != el) && el.hasOwnProperty('client')) {
el.client.SetValue(value);
}
}
This allows me to separate the display code and the web socket handling code as the web socket handling code is re-used for multiple HTML pages. I have used a similar pattern with a lot of success in my code, but this is failing.
The value is not being displayed and the web console is displaying the following error:
ReferenceError: value is not defined
Experimentation shows that this is because Vue thinks that there is no variable called "value" within the "data" part of the component.
Elsewhere I have another Vue component that is more complex. It has multiple values that are used, and updated, in a similar fashion. It works fine.
Vue.component('NavPane', {
template: `<table class="fixed">
...
<td v-html="speed"></td>
...
data: function () {
return {
...
speed: ''
}
},
mounted: function() {
},
methods: {
}
});
When you boil it down, this code is doing exactly the same thing as the failing code, but this component works.
You've got a small mistake here:
data: function () {
value: ''
},
You've merged the braces from a function declaration and an object literal. It should be something like this:
data: function () {
return {
value: ''
}
},

How to compute a property based on an object with fallback

I have a component that receives an object as prop, like this:
props: ['propObject']
Then, there's a default object defined (I use VueX, so it's actually defined as a $store getter, but to make it simpler, let's say it's defined in the data method) in the data:
data() {
return {
dataObject: {defaultValueA: 1, defaultValueB: 2}
}
}
And I'd like to have a computed property that would behavior like this:
computed: {
computedObject() {
return Object.values(this.propObject).length > 0 ? this.propObject : this.dataObject;
}
}
However, I know this is not possible because Vue watchers don't watch for changes in the key/value pairs of an object.
I have tried to go with a watched property, like this:
props: ['propObject'],
data() {
return {
object: {},
defaultObject: {}
}
},
watch: {
propObject: {
handler: function() {
this.setComputedObject();
},
deep: true
}
},
methods: {
setComputedObject() {
this.object = Object.values(this.propObject).length > 0 ? this.propObject : this.defaultObject;
}
},
mounted() {
this.setComputedObject();
}
However, the watcher handler is not being called at all when the propObject changes, but if I call it directly via console, it works. Is there any way that I can make the computedObject become reactive?
you need to use Vue.set/vm.$set where you change the props (in source component)
for example
changeProp(){
this.$set(propObject,'newprop','newval');
}
and then just you regualr compouted in the target component (the component which receive the prop)
source : https://v2.vuejs.org/v2/guide/list.html#Object-Change-Detection-Caveats

Computed property was assigned to but it has no setter

What is the correct syntax/hooks to make this work for myVal?
My code looks like this:
<v-item-group v-model="myVal" ...
import { mapActions, mapGetters } from 'vuex';
export default {
computed : {
...mapActions({
myVal: 'myModulePath/setMyVal'
}),
...mapGetters({
myVal: 'myModulePath/getMyVal'
}),
},
}
The store looks like:
actions: {
setMyVal({commit}, value){commit('someMutation',value);}
getters: {
getMyVal: state => { return state.myVal;}
I'm not sure how to wire it so the 'setter' works and the error message goes away.
I've also tried this to no avail:
...mapState('myModulePath', ['myVal'])
You need to define a single computed with a get and a set function. Maybe:
export default {
computed : {
myVal: {
get() { return this.$store.getters.getMyVal; },
set(newValue) { this.$store.dispatch('setMyVal', newValue); }
}
},
}
You need to tell the vue component what to do when the computed property is assigned a new value
computed: {
myVal: {
get: () => this.$state.store.getters.myModulePath.getMyVal,
set: (value) => this.$state.commit('someMutation', value )
}
}
Note that I use the setter instead of the action. Using an action in the computed property setter is a bad idea because actions are usually asynchronous and can cause headaches trying to debug the computed property later.

How to access nested functions in Vue.js?

Say, we have a Vue.js component built this way:
export default {
watch: {
// vars
}
},
methods: {
functionOne: function() {
function nestedFuncOne(p, q) {
// doing something
}
},
functionTwo: function() {
function nestedFuncTwo(r, s) {
// doing something
}
nestedFuncOne(param1, param2); // how to call it?
}
},
(...)
How should an inner function from the first method be called from inside of second method? this seems not to give desired output here.