首先,我遇到了一个两个分离的前端项目,该父类组件调用子类组件时,不论是写在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>

这个问题到这里,得到了解决。可能就是没遇到这种情况,生命周期就完全没理解到位,哈哈!

Logo

前往低代码交流专区

更多推荐