Reputation: 12669
I'm not sure why my props aren't updating when I update the data in my parent component. I've tried it out in a fiddle and it works https://jsfiddle.net/f3w69rr6/1/ but it doesn't work in my app.
parent:
methods: {
addToHand(index) {
let card = this.gameState.playerDeck.splice(index, 1)
if (this.gameState.playerHand.length < 12)
{
// put card into hand
this.$set(this.gameState, 'playerHand', [...this.gameState.playerHand, card])
// this.gameState.playerHand.push(card)
}
// otherwise discard card
},
retrieveDeck() {
let array = []
for (let i = 0; i < 20; i++)
{
array.push(this.src + "?text=card"+i)
}
this.$set(this.gameState, 'playerDeck', array)
},
},
mounted () {
this.retrieveDeck()
for (let i = 0; i < 5; i++)
{
this.addToHand(1)
}
},
putting the data into child via:
<PlayerCards :gameState="gameState" :hand="gameState.playerHand" />
child:
export default {
name: 'PlayerCards',
props: ["gameState", "hand"],
data() {
return {
}
},
computed: {
rows() {
let cards = this.gameState.playerHand
let max = 6;
if (cards.length <= max)
return [cards]
var mid = Math.ceil(cards.length / 2);
let return_value = [cards.slice(0, mid), cards.slice(mid)]
return return_value
}
}
}
but the row content is empty.
Update (Updated fiddle):
The problem is with the compute
https://jsfiddle.net/f3w69rr6/1/
Upvotes: 1
Views: 4172
Reputation: 32724
If you're not using string templates then you need to use the kebab-case
equivalent to your camelCase
prop:
<PlayerCards :game-state="gameState" :hand="gameState.playerHand" />
The reason it works in your fiddle is because you are using a string template (see: https://v2.vuejs.org/v2/guide/components.html#camelCase-vs-kebab-case)
Upvotes: 2
Reputation: 12669
I believe this was due to a misuse of the computed
property. Switching it over to data
and using this.$set
updates as expected. If I were to use computed
then setters would be needed. Computed also seems to be more suited for combining/updating data
properties rather than being a property in and of itself.
Upvotes: 0
Reputation: 11
Look at your demo in jsfiddle:
rows() {
let cards = this.gameState.playerHand
let max = 6;
if (cards.length <= max)
return [cards]
var mid = Math.ceil(cards.length / 2);
let return_value = [cards.slice(0, mid), cards.slice(mid)]
return return_value
}
Actually, vue has notified the computed function successfully when gameState.playerHand
has updated. But you wrapped the computed property: rows
into an array, like: [cards]
and [cards.slice(0, mid), cards.slice(mid)]
. And obviously, the rows.length
will be 1
or 2
.
Upvotes: 0