I've copied the Grid Component Example into a single-file component (Grid.vue
). Within that component, I'm not able to access the columns
prop. console.log(this.columns)
always prints: [__ob__: Observer]
to the log. Can someone tell me why? This works fine in their example on the page and in JSFiddle.
Here's my Grid.vue
file:
<script>
export default {
name: 'grid',
props: {
data: Array,
columns: Array,
filterKey: String
},
data: function() {
var sortOrders = {}
console.log(this.columns)
this.columns.forEach((column) => {
sortOrders[column] = 1
});
return {
sortCol: '',
sortOrders: sortOrders
}
},
computed: {
filteredData: function () {
var sortCol = this.sortCol
var filterKey = this.filterKey && this.filterKey.toLowerCase()
var order = this.sortOrders[sortCol] || 1
var data = this.data
if (filterKey) {
data = data.filter((row) => {
return Object.keys(row).some((key) => {
return String(row[key]).toLowerCase().indexOf(filterKey) > -1
})
})
}
if (sortCol) {
data = data.slice().sort((a, b) => {
a = a[sortCol]
b = b[sortCol]
return (a === b ? 0 : a > b ? 1 : -1) * order
})
}
return data
}
},
filters: {
capitalize: function (str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
},
methods: {
sortBy: function (key) {
this.sortCol = key
console.log(this.sortOrders[key])
this.sortOrders[key] = this.sortOrders[key] * -1
console.log(this.sortOrders[key])
}
},
created() {
},
mounted() {
// var app = this
},
}
</script>
I'm using this component within another component like so:
<template>
<div>
<form id="search">
Search <input name="query" v-model="searchQuery">
</form>
<grid :data="things" :columns="thingColumns" :filterKey="searchQuery"></grid>
</div>
</template>
<script>
import Grid from './Grid.vue';
export default {
name: 'things-grid',
data: function() {
return {
things: [],
thingColumns: [],
searchQuery: ''
}
},
mounted() {
var app = this
app.things = [
{id: 1, this: 'this 1', that: 'that 1', thing: 'thing 1'},
{id: 2, this: 'this 2', that: 'that 2', thing: 'thing 2'},
{id: 3, this: 'this 3', that: 'that 3', thing: 'thing 3'},
{id: 4, this: 'this 4', that: 'that 4', thing: 'thing 4'},
{id: 5, this: 'this 5', that: 'that 5', thing: 'thing 5'},
]
app.thingColumns = [
'this', 'that', 'thing'
]
app.searchQuery = ''
},
components: { Grid }
}
</script>
答案 0 :(得分:1)
In:
<grid :data="things" :columns="thingColumns" :filterKey="searchQuery"></grid>
The value of this.thingColumns
is passed as :columns
when mounting.
Thus, the console.log(this.columns)
inside Grid.vue/data()
prints when it is mounting.
And when it is mounting, thingColumns
is empty in the parent:
data: function() {
return {
things: [],
thingColumns: [], // initially empty
searchQuery: ''
}
},
mounted() {
var app = this
// ...
app.thingColumns = [ // this code only runs after it is mounted
'this', 'that', 'thing'
]
// ...
},
Since the console.log(this.columns)
inside Grid.vue/data()
prints when it is mounting, that is, before it is mounted, it prints an empty array:
[__ob__: Observer] // this is an empty array, the __ob__ thing is related to Vue internals
Because, well, parent's thingColumns
will only have data after the mounted()
hook executes.
And since it is a reactive array, when you update it, it will update the child grid
component as well.
Move the property initalization code from mounted()
to created()
:
created() { // was mounted()
var app = this
// ...
app.thingColumns = [
'this', 'that', 'thing'
]
// ...
},
This will initialize the data sooner and make it available in time for the console.log()
in the child to pick it up.