Vue父组件方法和子组件方法执行优先顺序
vue父组件调用子组件方法时,当方法中用到父组件传入的数据,在调用方法之前修改数据,调用子组件方法时数据还是原来的数据,下一次调用时才会变成上一次修改的数据。
首先,我遇到了一个两个分离的前端项目,该父类组件调用子类组件时,不论是写在mounted还是created中,明明两个方法应该按照顺序执行,和我想的完全不一样,子组件的方法优先执行,父类的方法永远在子组件的方法执行后。
我想要的需求是父组件的方法从后台拿到数据,更新到子组件中,让子组件拿到这个值,进行处理。
类似于这个问题:Vue 父组件调用子组件方法时prop延迟问题
下面,我简单的用代码模拟问题:
尝试第一种解决思路:
// 父组件
<template>
<component :is="mainName" :parameter="pars"></component>
</template>
<script>
export default {
data(){
return {
pars:{
arr:[]
}
}
}
....
mounted(){
this.getData()
},
methods:{
getData(){
// 从后台拿到值
arr.push(1);
}
}
}
</script>
// 子组件
<script>
export default {
...
props: {
parameter: {
type: Object,
required: true
}
},
created(){
},
mounted(){
this.init()
},
methods:{
init(){
// 调用提示信息
this.$message(parameter.arr);
}
}
}
</script>
该现象非常奇怪,会先执行子组件方法,然后在执行父组件方法,这样的话,想要更新传值就没用了。
还有就是一种,你看这个博客,写的很好,实际上却是另一种情况,我吐了。
// 父组件
<template>
<component :is="mainName" :parameter="pars"></component>
</template>
<script>
export default {
data(){
return {
pars:{
arr:[]
}
}
}
....
created(){
this.getData()
},
mounted(){
//this.getData()
},
methods:{
getData(){
// 从后台拿到值
arr.push(1);
}
}
}
</script>
// 子组件
<script>
export default {
...
props: {
parameter: {
type: Object,
required: true
}
},
created(){
},
mounted(){
this.init()
},
methods:{
init(){
// 调用提示信息
this.$message(parameter.arr);
}
}
}
</script>
什么父created->子created->子beforeMount->子mounted执行顺序,你是测试过吗?根本没用,坑死人了。
第二种思路,我尝试上面那篇回答,可惜回答只是一种思路,还是让我花费了大量的时间。经过测试,也完全没有用处。
通过ref调用子组件的方法。
// 父组件
<template>
<component :is="mainName" :parameter="pars" ref="login"></component>
</template>
<script>
export default {
data(){
return {
pars:{
arr:[]
}
}
}
....
mounted(){
this.getData()
this.$refs.login.init()
},
methods:{
getData(){
// 从后台拿到值
arr.push(1);
}
}
}
</script>
// 子组件
<script>
export default {
...
props: {
parameter: {
type: Object,
required: true
}
},
created(){
},
mounted(){
// this.init()
},
methods:{
init(){
// 调用提示信息
this.$message(parameter.arr);
}
}
}
</script>
可惜,结果还是和上面的一样。
第三种思路,我使用了computed让它进行缓存,是的,让人值得高兴,computed的优先级较高,父组件第一次优先执行了。
// 父组件
<template>
<component :is="mainName" :parameter="pars" ref="login"></component>
</template>
<script>
export default {
data(){
return {
pars:{
arr:[]
}
}
}
....
mounted(){
// this.getData()
this.$nextTick(() => {
this.getArr()
})
this.$refs.login.init()
},
computed: {
getArr(){
// 从后台拿到值
arr.push(1);
}
}
methods:{
}
}
</script>
// 子组件
<script>
export default {
...
props: {
parameter: {
type: Object,
required: true
}
},
created(){
},
mounted(){
// this.init()
},
methods:{
init(){
// 调用提示信息
this.$message(parameter.arr);
}
}
}
</script>
这样的方式,还是那样,又一次失败了。
不过,我又想到另一种方式,使用watch来监听值的变化:
// 父组件
<template>
<component :is="mainName" :parameter="pars" ref="login"></component>
</template>
<script>
export default {
data(){
return {
pars:{
arr:[]
}
}
}
....
mounted(){
// this.getData()
//this.$nextTick(() => {
// this.getArr()
//})
//this.$refs.login.init()
},
computed: {
getArr(){
// 从后台拿到值
arr.push(1);
}
}
methods:{
},
watch: {
getArr : function (oldVal, newVal) {
console.log(newVal)
console.log(oldVal)
this.$refs.login.init()
}
}
}
</script>
// 子组件
<script>
export default {
...
props: {
parameter: {
type: Object,
required: true
}
},
created(){
},
mounted(){
// this.init()
},
methods:{
init(){
// 调用提示信息
this.$message(parameter.arr);
}
},
}
</script>
这一次成功的让父组件优先执行了,但是这两个东西一起用时,直接陷入死循环了,computed调完在调watch,两个监听相互调,然后就出现冒泡事件。
经过我的思考,最终修改了watch的监听值,终于这一切都美好起来了。
// 父组件
<template>
<component :is="mainName" :parameter="pars" ref="login"></component>
</template>
<script>
export default {
data(){
return {
pars:{
arr:[]
}
}
}
....
mounted(){
this.getArr()
//this.$nextTick(() => {
// this.getArr()
//})
//this.$refs.login.init()
},
computed: {
//getArr(){
// 从后台拿到值
//arr.push(1);
//}
}
methods:{
getArr(){
// 从后台拿到值
arr.push(1);
}
},
watch: {
'pars.arr' : function (oldVal, newVal) {
console.log(newVal)
console.log(oldVal)
this.$refs.login.init()
}
}
}
</script>
// 子组件
<script>
export default {
...
props: {
parameter: {
type: Object,
required: true
}
},
created(){
},
mounted(){
// this.init()
},
methods:{
init(){
// 调用提示信息
this.$message(parameter.arr);
}
},
}
</script>
这个问题到这里,得到了解决。可能就是没遇到这种情况,生命周期就完全没理解到位,哈哈!
更多推荐
所有评论(0)