How to display the value of a variable - vue.js

Gets data from collection:
const pageTitles = {
homePage: 'Main'
...
}
export default pageTitles
If I make all this way:
<div><span>{{pageTitles.homePage}}</span></div>
everything is ok.
But i need to show the value depending on route. I tried to make this:
pageTitle(){
if (this.$route.path === '/'){
return pageTitles.homePage
}
}
and in div I have {{pageTitle}}, but it doesn't work. Why it doesn't work?

you've omitted the this keyword before pageTitles.homePage in your computed property
pageTitle(){
if (this.$route.path === '/'){
return this.pageTitles.homePage
}
}

It should work, Here you go :
new Vue({
el: '#app',
data: {
pageTitles: {
homePage: 'Main'
}
},
computed: {
pageTitle() {
return this.pageTitles.homePage
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>{{ pageTitle }}</h2>
</div>

Related

How to inject object value to v-text when key was added during usegn aplication?

This is my obj form backend
myObj = {
name:'nr123',
empty:''
}
On click function adds new key: value
function userClick(){
this.myObj.status= "accept";
console.log(this.myObj)
}
clg returns
myObj = {
name:'nr123',
empty:'',
satus:'accept'
}
but when i try to display it
<v-text>
Acceptation status {{ myObj.status }}
</v-text>
it won't work.
And this is iteresting when i use "epty" (alredy declared key) to carry 'accept' every thing works fine
so how to show acceptation status when it was added in a midle of the process?
(myObj is one of dinamicly created objects kept in array. Each of myObj's can assume diferent acceptation status)
You can use computed property.
Demo :
new Vue({
el: '#app',
data() {
return {
myObj: {
name:'nr123',
empty:''
}
}
},
computed: {
newObj: function() {
this.myObj.status = 'accept';
return this.myObj;
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<p v-text="newObj.status"></p>
</div>

How do I trigger a recalculation in a Vue app?

I'm working on a project with Vue and VueX. In my component, I have a calculated method that looks like this:
...mapState([
'watches',
]),
isWatched() {
console.log('check watch');
if (!this.watches) return false;
console.log('iw', this.watches[this.event.id]);
return this.watches[this.event.id] === true;
},
And in my store, I have the following:
addWatch(state, event) {
console.log('add', state.watches);
state.watches = {
...state.watches,
[event]: true,
};
console.log('add2', state.watches);
},
However, this doesn't trigger a recalculation. What's going on?
Try changing return this.watches[this.event.id] === true;
to
return this.$store.commit("addWatch", this.event.id);
The code you have shown is correct, so the problem must be elsewhere.
I assume by 'calculated method' you mean computed property.
Computed properties do not watch their dependencies deeply, but you are updating the store immutably, so that is not the problem.
Here is a bit of sample code to give you the full picture.
Add event numbers until you hit '2', and the isWatched property becomes true.
Vue.use(Vuex);
const mapState = Vuex.mapState;
const store = new Vuex.Store({
state: {
watches: {}
},
mutations: {
addWatch(state, event) {
state.watches = { ...state.watches, [event]: true };
}
}
});
new Vue({
el: "#app",
store,
data: {
numberInput: 0,
event: { id: 2 }
},
methods: {
addNumber(numberInput) {
this.$store.commit("addWatch", Number(numberInput));
}
},
computed: {
...mapState(["watches"]),
isWatched() {
if (!this.watches) return false;
return this.watches[this.event.id] === true;
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.1.0/vuex.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div>Watches: {{ watches }}</div>
<div>isWatched: {{ isWatched }}</div>
<br>
<input v-model="numberInput" type="number" />
<button #click="addNumber(numberInput)">
Add new event
</button>
</div>

Adding a "Default" image to my <img> (VUE)

I have an area where people can upload their own user-image. But if they do not, I would like to display a default one.
After some googling, I found I can do so by doing something like -
<img :src="creatorImage" #error="defaultAvatar">
But, I am not sure how to then created a method to pass the correct (default) image into it.
I did it with a computed property, like this:
<template>
<img :src="creatorImage" #error="imageError = true"/>
</template>
<script>
...
data() {
return {
imageError: false,
defaultImage: require("#/assets/imgs/default.jpg")
};
},
computed: {
creatorImage() {
return this.imageError ? this.defaultImage : "creator-image.jpg";
}
}
...
</script>
I would suggest creating a component for this, as it sounds like something that will be used on more places.
JsFiddle example
Component
Vue.component('img-with-default', {
props: ['defaultImg'],
data: function () {
return {
defaultAvatar: this.defaultImg || 'https://cdn0.iconfinder.com/data/icons/crime-protection-people/110/Ninja-128.png'
}
},
computed:{
userImage: function() {
if(this.uploadedImg != null) {
return this.uploadedImg;
} else {
return this.defaultAvatar;
}
}
},
template: '<img :src="userImage">'
})
And using the commponent would be
HTML
<div id="editor">
<img-with-default></img-with-default>
<img-with-default default-img="https://cdn3.iconfinder.com/data/icons/avatars-15/64/_Ninja-2-128.png" ></img-with-default>
</div>
JS
new Vue({
el: '#editor'
})
With this you have the default image.
If you want you can create a component that would display passed img src or the default one.
Component
Vue.component('img-with-default', {
props: ['imgSrc'],
data: function () {
return {
imageSource: this.imgSrc || 'https://cdn0.iconfinder.com/data/icons/crime-protection-people/110/Ninja-128.png'
}
},
template: '<img :src="imageSource">'
})
and to use it
HTML
<div id="editor">
<img-with-default></img-with-default>
<img-with-default img-src="https://cdn3.iconfinder.com/data/icons/avatars-15/64/_Ninja-2-128.png" ></img-with-default>
</div>

Vue JS: Setting computed property not invoking v-if

When a method sets a computed property, v-ifs are not getting invoked. I thought a computed property logically worked just like a 'regular' property.
// theState can't be moved into Vue object, just using for this example
var theState = false;
var app = new Vue({
el: '#demo',
data: {
},
methods: {
show: function() {
this.foo = true;
},
hide: function() {
this.foo = false;
}
},
computed: {
foo: {
get: function() {
return theState;
},
set: function(x) {
theState = x;
}
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="demo">
<input type=button value="Show" #click="show()">
<input type=button value="Hide" #click="hide()">
<div v-if="foo">Hello</div>
</div>
Am I doing something wrong?
Vue doesn't observe changes in variables outside the component; you need to import that value into the component itself in order for the reactivity to work.
var theState = false; // <-- external variable Vue doesn't know about
var app = new Vue({
el: '#demo',
data: {
myState: theState // <-- now Vue knows to watch myState for changes
},
methods: {
show: function() {
this.foo = true;
theState = true; // <-- this won't affect the component, but will keep your external variable in synch
},
hide: function() {
this.foo = false;
theState = false; // <-- this won't affect the component, but will keep your external variable in synch
}
},
computed: {
foo: {
get: function() {
return this.myState;
},
set: function(x) {
this.myState = x;
}
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="demo">
<input type=button value="Show" #click="show()">
<input type=button value="Hide" #click="hide()">
<div v-if="foo">Hello</div>
</div>
(Edited to remove incorrect info; I forgot computed property setters existed for a while there)
You need to move theState into data. Otherwise it wont be reactive, so vue wont know when its changed, so v-if or any other reactivity wont work.
var app = new Vue({
el: '#demo',
data: {
foo2: false,
theState: false
// 1
},
methods: {
show: function() {
this.foo = true;
},
hide: function() {
this.foo = false;
}
},
computed: {
foo: { // 2
get: function() {
return this.theState
},
set: function(x) {
this.theState = x;
}
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="demo">
<input type=button value="Show" #click="show()">
<input type=button value="Hide" #click="hide()">
<div v-if="foo">Hello</div>
</div>

How to set data to other Component in Vuejs

I want to set data from a component to another component with vuejs. Here's my code:
http://quangtri.herokuapp.com/s/ByNN4FE-b
Where am I wrong? Please help me! Thank you very much!
You are using a function in your bus.$on, so this is not what you think it is. Use an arrow function instead and it works.
const bus = new Vue();
Vue.component('coupon', {
data() {
return {
name: 'tri'
}
},
template: `
<div>
<p>{{ name }}</p>
<button type="button" #click="batdau">Go</button>
</div>
`,
methods: {
batdau(name) {
this.name = 'Maria';
}
},
created() {
},
mounted() {
bus.$on('applied', (name) => {
alert(name);
this.name = 'Romeo';
})
}
});
Vue.component('couponmore', {
template: `
<button type="button" #click="nosukien">Let Set Name</button>
`,
methods: {
nosukien() {
bus.$emit('applied', 'John');
}
}
});
new Vue({
el: '#root',
data: {
couponApplied: false
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.min.js"></script>
<div id="root">
<coupon></coupon>
<couponmore></couponmore>
</div>
That's because in that piece of code, this is window, not the component.
bus.$on('applied', function(name){
alert(name);
this.$data.name ='Romeo';
})
Also you are setting data using this.$data.name instead of simply this.name, I'm not sure about it, but this could result in reactive data issues.
Solution:
If you are using ES6, you can do this:
bus.$on('applied', (name) => {
alert(name);
this.name ='Romeo';
})
This is called arrow function, and when using an arrow function instead of a normal function, the value of this inside the function will be the same as in the parent scope (so, the component instance who contains data).
If you are using vanilla javascript, use .bind(this) at the end:
bus.$on('applied', function (name) {
alert(name);
this.name ='Romeo';
}.bind(this))