vue父组件传递props异步数据到子组件遇到的问题
父组件parent.vue
1 | // asyncData为异步获取的数据,想传递给子组件使用 |
情况1
子组件child.vue
1 | <template> |
在这种情况下,子组件中html
中的{{childData}}
值会随着父组件传过来的值而改变,这是数据的响应式变化(数据的改变会引起界面变化),但子组件created
函数中是拿不到父组件异步传过来的数据的,这是生命周期问题。
情况2
子组件child.vue
1 | <template> |
created
里面的仍然是空值, 子组件的html
中的{{childObject.items[0]}}
的值虽然会随着父组件的值而改变,但是过程中会报错。
是因为:首先传过来的是空,然后再异步刷新值,也就是开始时候childObject.items[0]
等同于''.item[0]
这样的操作,
所以就会报下面的错:
解决办法
使用
v-if
可以解决报错问题和created
为空问题父组件
parent
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30<template>
<div>
父组件
<child :child-object="asyncObject" v-if="flag"></child>
<!--没拿到数据前,不渲染子组件,这样子组件created生命周期就能拿到数据了-->
</div>
</template>
<script>
import child from '../demo1/children.vue'
export default {
data: () => ({
asyncObject: '',
flag:false
}),
components: {
child
},
created () {
},
mounted () {
// setTimeout模拟异步数据
setTimeout(() => {
this.asyncObject = {'items': [1, 2, 3]}
this.flag= true
console.log('parent 结束')
}, 2000)
}
}
</script>子页面 children
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19<template>
<div>
子组件
<p>{{childObject.items[0]}}</p>
</div>
</template>
<script>
export default {
props: ['childObject'],
data: () => ({
}),
created () {
console.log("子组件create-----"+JSON.stringify(this.childObject)) //能拿到了
},
methods: {
}
}
</script>子组件使用
watch
来监听父组件改变的prop
,使用methods
来代替created
子组件 children
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25<template>
<div>
<p>{{test}}</p>
</div>
</template>
<script>
export default {
props: ['childObject'],
data: () => ({
test: ''
}),
watch: {
'childObject.items': function (new, old) { // 直接监听childObject.item属性
this.test = new[0]
this.updata()
}
},
methods: {
updata () { // 既然created只会执行一次,但是又想监听改变的值做其他事情的话,只能搬到这里咯
console.log(this.test)// 1
}
}
}
</script>子组件
watch computed data
相结合(麻烦,不推荐)子组件children
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35<template>
<div>
<p>{{test}}</p>
</div>
</template>
<script>
export default {
props: ['childObject'],
data: () => ({
test: ''
}),
watch: {
'childObject.items': function (n, o) {
this._test = n[0]
}
},
computed: {
_test: {
set (value) {
this.update()
this.test = value
},
get () {
return this.test
}
}
},
methods: {
update () {
console.log(this.childObject) // {items: [1,2,3]}
}
}
}
</script>使用
prop default
来解决{{childObject.items[0]}}
父组件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27<template>
<div>
父组件
<child :child-object="asyncObject"></child>
</div>
</template>
<script>
import child from '../demo4/children.vue'
export default {
data: () => ({
asyncObject: undefined // 这里使用null反而报0的错
}),
components: {
child
},
created () {
},
mounted () {
// setTimeout模拟异步数据
setTimeout(() => {
this.asyncObject = {'items': [1, 2, 3]}
console.log('parent finish')
}, 2000)
}
}
</script>子组件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26<template>
<div>
子组件<!--1-->
<p>{{childObject.items[0]}}</p>
</div>
</template>
<script>
export default {
props: {
childObject: {
type: Object,
default () {
return {
items: ''
}
}
}
},
data: () => ({
}),
created () {
console.log(this.childObject) // {item: ''}
}
}
</script>