How can I set the value of name to the property personOne in object? So that name will have the value of Alex.
var app = new Vue({
el: '#app',
data: {
name: '',
object: { "personOne": "Alex", "personTwo": "Jack"}
}
})
From within the Vue object you write
this.name = 'Alex' and outside you write app.name = 'Alex'
app.someDataField will change the data property called someDataField
You can use one of the life-cycle hooks like created created or mounted for setting initial data, loading data from API, etc, like following:
var app = new Vue({
el: '#app',
data: {
name: '',
object: { "personOne": "Alex", "personTwo": "Jack"}
},
methods: {
setName (name) {
this.name = name
}
},
mounted () {
this.setName(this.object.personOne)
},
})
Related
I am currently faced with a situation where I add options to a select element via vuejs when the #change of that specific element is called.
The problem is that the new option is not 'registered' until I leave the function.
I made a jsfiddle to demonstrate this behaviour: https://jsfiddle.net/bz8361Lp/
In this demo, if a option in the select element is selected, a new option is added to the select. The console is still printing the old number of entries.
new Vue({
el: "#app",
data: {
data: ["test", "hallo", "bye"]
},
methods: {
onChange(event) {
console.log("test")
this.data.push("hello")
const element = document.getElementById("select")
console.log(element.options.length)
}
}
})
I am looking for some guidance on how I can avoid this problem, what I am doing wrong and what a best practice could be.
Thanks.
This is because Vue.js updates DOM not immediately but on the next event loop processing.
You can read about this in detail here
You can check this by using nextTick:
onChange(event) {
console.log("test")
this.data.push("hello")
this.$nextTick(() => {
const element = document.getElementById("select")
console.log(element.options.length)
});
}
need to wait for the dom to render and then evaluate. You can find more information about what the function does '' this.$nextTick()
new Vue({
el: "#app",
data: {
data: ["test", "hallo", "bye"]
},
methods: {
onChange(event) {
console.log("test")
this.data.push("hello")
this.$nextTick(() => {
const element = document.getElementById("select")
console.log(element.options.length)
})
}
}
})
I have to add extra rows forcing Vue to recompute computed prop, specifically:
var foo = this.groups;
this.groups = {};
this.groups = foo;
as can be seen in this fiddle: https://jsfiddle.net/8bqv29dg/. Without these, available_groups is not updated.
Why is that and what is the clean way to have available_groups updating with groups?
Have tried adding groups to "deep-watched", but it did not help.
Use $set to add new property for data object:
methods: {
add_group: function(key, name) {
this.$set(this.groups, key, {key, name});
},
}
Here described vue reactivity
Vue doesn't track new elements added to an object:
https://v2.vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats
One solution is to use Vue.set or reassign the object, like the example below:
new Vue({
el: "#app",
data: {
groups: {1: {key: 1, label: 'Those guys'}},
},
computed: {
available_groups: function() {
return [{value: 0, label: 'Anyone'}].concat(Object.values(this.groups));
},
},
methods: {
add_group: function(key, name) {
Vue.set(this.groups, key, {key: key, name: name})
},
}
})
So I have the following data, and my goal is to recalculate the user's results every time data in this object is changed. Here is the data.
data() {
return {
test: 0,
userData: {
sex: null,
age: null,
feet: null,
inches: null,
activity: null,
goal: null,
},
}
}
Now I have tried to implement both watch and computed, but it seams Vue is not noticing when individual items in the object are changed. However, if I take some data out of the object it does notice the change.
Here is what I tried for watch:
watch: {
userData: function () {
console.log("Changed");
}
}
The result was nothing in the console.
For computed I tried the following:
computed: {
results: function () {
console.log(this.userData);
return this.userData.sex;
}
}
But again nothing was printed in the console.
If I tried with the test variable:
watch: {
test: function () {
console.log("Changed");
}
}
It WOULD output changed when the variable was changed. So that works because it is not an object.
Any help would be very appreciated. Again the goal is to recalculate results whenever any userData is changed.
Here is one way to do it. You need (as #match mentioned) use Vue.set() or vm.$set(). I found it was also necessary to update your watcher property to userData.sex.
new Vue({
el: "#app",
data: {
status: '',
userData: {
sex: ''
},
},
methods: {
updateValues(){
// Or Vue.set()
this.$nextTick( function(){
const newUserData = Object.assign({}, this.userData);
newUserData.sex = "Male";
this.userData = newUserData;
});
}
},
watch: {
userData: function (v) {
this.status += "userData Changed";
},
'userData.sex': function (v) {
this.status += "\nuserData.sex Changed";
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.8/dist/vue.min.js"></script>
<div id="app">
<pre v-text="'userData.sex = ' + userData.sex"></pre>
<pre v-text="status"></pre>
<button #click="updateValues()">
Change Sex
</button>
</div>
EDIT:
Re-assigning the whole object, userData, triggers the watch.userData.
Are you actually using the results property (in your template for example)? Computed properties do not get recomputed if they are not being used.
As opposed to what #match says, I doubt you have a reactivity problem since you do not add or delete properties (they already exist in your data so they are already reactive).
Tell me please, how in DATA to write data from the AJAX response?
Example:
var example = new Vue({
el: '#example',
data:{
myArr: []
},
created: function () {
$.getJSON('data.json', function(data) {
this.myArr = data;
});
}
});
The problem is that in myArr, the response data is not written. How to solve this? Thank you.
Can you try this ? Basically this inside the ajax is not exactly the one you would expect.
var example = new Vue({
el: '#example',
data:{
myArr: []
},
created: function () {
var vm = this;
$.getJSON('data.json', function(data) {
vm.myArr = data;
});
}
});
You can also use reactivity setting method $set instead of directly assigning to the vm.myArr : https://v2.vuejs.org/v2/guide/reactivity.html
I'm really struggling to get the most basic REST functionality to work in vue.js 2.
I'd like to get data from some endpoint and assign the returned value to a variable of my Vue instance. Here's how far I got.
var link = 'https://jsonplaceholder.typicode.com/users';
var users;
Vue.http.get(link).then(function(response){
users = response.data;
}, function(error){
console.log(error.statusText);
});
new Vue ({
el: '#user-list',
data: {
list: users
}
});
Inside the promise, I can access the response data, but I cannot seem to assign it to users or even to data of the Vue instance.
Needless to say, I'm completely new to vue.js and thankful for any help.
Stack: vue.js 2.03, vue-resource 1.0.3
Cheers!
You can create an object and pass it to the vue instance like that :
var link = 'https://jsonplaceholder.typicode.com/users';
var data = {
list: null
};
Vue.http.get(link).then(function(response){
data.list = response.data;
}, function(error){
console.log(error.statusText);
});
new Vue ({
el: '#app',
data: data
});
Or you can create a function under the methods object and then call it in the mounted function :
var link = 'https://jsonplaceholder.typicode.com/users';
new Vue ({
el: '#app',
data: {
list: null
},
methods:{
getUsers: function(){
this.$http.get(link).then(function(response){
this.list = response.data;
}, function(error){
console.log(error.statusText);
});
}
},
mounted: function () {
this.getUsers();
}
});