I am new to VUE and for one project I am trying to update an array passing the object. I have two button which is called BUTTON 1 and BUTTON 2. If you click on BUTTON 1 then it will set an object to list[] using this.$set. But when BUTTON 2 is pressed it should update with the new value and should display as
{
a:1,
b:2,
c:3
}
Right now I am using this.$set for button 2 as well and it removes the previous value then adds the new one as {c:3} only. Is there a way to add on value using VUE to display { a:1,b:2,c:3} when BUTTON 2 is clicked.
View
<div id="app">
<button #click="button1()">Button 1</button>
<button #click="button2()">Button 2</button>
</div>
Method
new Vue({
el: "#app",
data: {
list:[]
},
methods: {
button1(){
var b = '0';
this.$set(this.list, b, {
1:{
a: '1',
b: '2'
}
})
console.log(this.list);
},
button2(){
var b = '0';
this.$set(this.list, b,{
1:{
c: '3'
}
})
console.log(this.list);
},
}
})
Below there is a jsfiddle link for my code
https://jsfiddle.net/ujjumaki/enj3dwo6/19/
Hope this works.
new Vue({
el: "#app",
data: {
list:[]
},
methods: {
button1(){
console.log('button 1');
const b = '0';
const restObj=this.list[b] && this.list[b][1]
this.$set(this.list, b, {
1:{
...restObj,
a: '1',
b: '2'
}
})
console.log(this.list);
},
button2(){
const b = '0';
const restObj=this.list[b] && this.list[b][1]
this.$set(this.list, b,{
1:{
...restObj,
c: '3'
}
})
console.log(this.list);
},
}
})
Related
I am really new to Vue and for one project I am trying to create an array of objects according to a number. For example, if the total length value is 3 then is there a way to create fetchList1, fetchList2 and fetchList3? If the total length value is 2 then it should create the data return object as fetchList1 and fetchList2.
I am getting the total length value from database so it can be more than 50 and less than 5 sometimes.
VIEW
<div id="app">
<button #click="grabTeams()">
CLICK ME
</button>
</div>
Method
new Vue({
el: "#app",
data: {
totalLength: '3',
fetchList1: '',
/** if the total length is 3 then it should automatically create fetchList1, fetchList2 and fetchList3 **/
},
methods: {
toggle: function(todo){
todo.done = !todo.done
},
grabTeams(){
console.log('Total value length ' +this.totalLength);
for(let b=0; b < this.totalLength; b++){
console.log('value of '+b);
var replyDataObj1 = parseInt(b);
replyDataObj1={
"id" : b
}
this['fetchList'+b] = replyDataObj1;
}
},
}
})
Below is the link that I tried on jsfiddle
https://jsfiddle.net/ujjumaki/8xq9wn1m/14/
Vue will throw a warning if you try to dynamically add root data properties. From the docs:
Vue does not allow dynamically adding new root-level reactive properties to an already created instance.
Instead, make a fetchList array:
data() {
return {
fetchList: []
}
}
Add to it:
for(let b = 0; b < this.totalLength; b++){
this.$set(this.fetchList, b, {
id: b
})
};
You have to use this.$set (or Vue.set) because you are adding dynamic indexes to the array.
Here's a demo:
new Vue({
el: "#app",
data: {
totalLength: '10',
fetchList: [],
},
methods: {
toggle: function(todo){
todo.done = !todo.done
},
grabTeams(){
for(let b = 0; b < this.totalLength; b++){
this.$set(this.fetchList, b, {
id: b
})
}
}
}
})
<div id="app">
<button #click="grabTeams()">
CLICK ME
</button>
{{ fetchList }}
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
var vue_app = new Vue({
el: '#id1',
data: {
v1:[],
},
methods:{
pushUnique: function() {
this.v1.push({'id':1,'name':'josh'});
this.v1.push({'id':1,'name':'josh'}); //this should not work.
},
},
});
In above code the second push should not execute. I would like to keep id unique. How can this be done in Vue.
THanks
I would move to storing data in an object (keyed by id) and use a computed property to produce your v1 array. For example
data: {
v1obj: {}
},
computed: {
v1 () {
return Object.keys(this.v1obj).map(id => ({ id, name: this.v1obj[id] }))
}
}
Then you can use methods like Object.prototype.hasOwnProperty() to check for existing keys...
methods: {
pushUnique () {
let id = 1
let name = 'josh'
if (!this.v1obj.hasOwnProperty(id)) {
this.v1obj[id] = name
}
}
}
I am changing properties using some buttons. When I click the buttons the data is updated in the UI, even the computed1, but not the console.log("computed1"). I think it's because I am changing its properties and not the entire object. But if it's not triggered, why the UI is updated ? Could you explain me ? I couldn't find something like this in the documentation.
Code: https://jsfiddle.net/1hr7cy5d/
var example1 = new Vue({
el: '#example',
data: function() {
return {
item: {
aaa: 'aaa',
bbb: 'bbb',
ccc: 'ccc'
}
}
},
computed: {
computed1: function() {
console.log("computed1");
let item = this.item
return item;
},
},
methods: {
method1() {
console.log("method1")
this.item.aaa = 'xxxx';
},
method2() {
console.log("method2")
this.item["bbb"] = 'yyyyy';
},
method3() {
console.log("method3")
this.$set(this.item, "ccc", "zzzzz")
},
method4() {},
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="example">
<button #click="method1()">method1</button>
<button #click="method2()">method2</button>
<button #click="method3()">method3</button>
<button #click="method4()">method4</button>
<pre>{{item}}</pre>
<pre>{{computed1}}</pre>
</div>
In my Vue instance's data property, I have an array of strings.
data() {
return { myArray: [] }
}
This array is filled with words of a sentence. For example:
['Hi', 'my', 'name', 'is', 'foo']
I would like to output the sentence to a paragraph tag in my template one word at a time, with a 1 second delay in between, similar to how a teleprompter would work:
[0 sec] - Hi
[1 sec] - Hi my
[2 sec] - Hi my name
[3 sec] - Hi my name is
[4 sec] - Hi my name is foo
Any help is appreciated.
You can use setInterval and add a word on each iteration:
new Vue({
el: '#app',
data: {
array: ['Hi', 'my', 'name', 'is', 'foo'],
string: '' // here your string will be stored
},
methods: {
appendWords: function() {
const it = this.array[Symbol.iterator](); // convenient for yeilding values
const int = setInterval(() => { // time interval
const next = it.next(); // next value
if (!next.done) { // done = true when the end of array reached
this.string += ' ' + next.value; // concatenate word to the string
} else {
clearInterval(int); // when done - clear interval
}
}, 1000) // interval duration, 1s
}
},
mounted() {
this.appendWords(); // invoke function when ready
}
});
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<p>{{ string }}</p>
</div>
Code
new Vue({
el:"#app",
data:{
base: ['Hi', 'my', 'name', 'is', 'foo'],
timed: []
},
mounted(){
this.base.forEach((item, i) => {
setTimeout(() => {
this.timed.push(`[${i} sec] - ${this.base.slice(0, i + 1).join(" ")}`)
}, i * 1000)
})
}
})
Template
<div id="app">
<p v-for="time in timed">{{time}}</p>
</div>
Example.
Edit
So, for fun, I thought about how you might go about making a teleprompter simulation in javascript. This is pretty naive, but works for the amount of time that I've put into it.
new Vue({
el:"#app",
data:{
lines: [
'Hi, my name is Foo. I am a literal',
'programmer. This is a teleprompter',
'simulation. These lines should all',
'be about the same length. There are ',
'different strategies for making that',
'happen.'
],
show:[]
},
mounted(){
let currentIndex = 0
this.$el.addEventListener('animationend', () => {
this.show.push(this.lines[++currentIndex])
})
this.show.push(this.lines[0])
}
})
#keyframes revealText {
0% {
width:0%;
}
100% {
width:100%;
}
}
#app{
width: 500px;
margin: auto
}
h1 {
white-space:nowrap;
overflow: hidden;
animation: revealText 5s;
}
<script src="https://unpkg.com/vue#2.2.6/dist/vue.js"></script>
<div id="app">
<h1 v-for="line in show">{{line}}</h1>
</div>
I have a issue with javascript. Please take a look:
function Component(data)
{
var self = this;
self.Name = data.name;
}
function Testing() {
var self = this;
self.Components = [
{
A: new Component({
name: 'test1'
})
}, {
B: new Component({
name: 'test2'
})
}, {
C: new Component({
name: 'test3'
})
}];
}
Now what i am trying to do is, I want to access each component from Components array by its property name (A, B ,C ...). So for this i did and getting error:
var t = new Testing();
t.Components['A'].Name; ==> //Error: Cannot read property 'Name' of undefined
Whats the issue ?
To access the properties of Component using a key self.Components must be an object (associative array). The code attempts to access the array using a key, which is fine for associative arrays, but will not work for a regular array as declared in the code. Switching self.Components to an object literal will allow the properties to be accessed by key.
function Testing() {
var self = this;
self.Components = {
A: new Component({
name: 'test1'
}),
B: new Component({
name: 'test2'
}),
C: new Component({
name: 'test3'
})
};
}
JS FIDDLE: http://jsfiddle.net/fxfbe/
The problem is that Components defined in the Testing is an array, remove array and create simply as object..
function Testing() {
....
self.Components = {
A: new Component({
name: 'test1'
}),
B: new Component({
name: 'test2'
}),
C: new Component({
name: 'test3'
})
};
}