Vue 父子组件通信$ref调用踩坑
场景:
父组件中给子组件传值,然后在父组件中触发事件,同时更新传递给子组件的某个变量的值再调用子组件函数,此时如果直接调用,会导致父组件传递给子组件的值不能马上获取到!!
下面先看一段代码:
<template> 部分:
<view class="reg-btn"><button class="button my-btn" type="default" @click="submit('form')">提交</button>
</view><reg-common-login ref="loginRef" :confirm="confirm" :password="formData.password":orgCode="formData.orgCode" @openWait="openWaiting" @closeWait="closeWaiting">
</reg-common-login>
<vue> 部分:
data() {return {confirm: false, // 此处只关注这个变量的传递,其他省略}
},
methods: {// 省略其他函数定义 ...submit(form) {this.confirm = truethis.$refs.loginRef.login() // 问题所在!!}
}
子组件部分:
<template><view class="container"></view>
</template><script>export default {name: 'login',props: {confirm: {type: Boolean,default: false},// 省略其他...},data() {return { content: '',}},watch: {confirm: {immediate: true,handler(newVal) {if (newVal) {this.content = this.$t('visitor.reg_success_already',[this.user.loginName,this.orgCode])} else {this.content = this.$t('visitor.reg_success_no_login')}},}},methods: {login() {let _this = thisuni.showModal({title: '提示',content: _this.content,showCancel: _this.confirm,success: function (res) {if (res.confirm) {if (!_this.confirm) {// 使用当前注册账号登录,登录成功后跳转到个人中心_this.toLogin(false)} else {// 用户已登录,使用当前注册账号进行切换登录,需要先退出当前账号_this.toLogin(true)}} else if (res.cancel) {// 用户已登录,不切换账号,跳转到首页_this.$Router.replace({name: 'home'})}}})},loginOut () {},toLogin(needLogout) {this.$emit('openWait')if (needLogout) {this.loginOut()}let _this = thissetTimeout(() => {_this.autoLogin()},3000)},autoLogin() {},}}
</script><style scoped lang="scss"></style>
这里重点看一下父组件的提交事件,触发事件后,同时更新了一下要传递给子组件的变量 confirm 的值,然后直接调用了子组件的函数,乍一看,没什么问题,一切都正常。
再看子组件,接收值、定义函数都没问题,但是这里注意一下,方法内的弹窗显示内容是动态的,是根据 confirm 来动态展示内容及是否需要展示取消按钮的:
当按照父组件中那样的写法来调用时,子组件的 confirm 值永远是 false,这里就是本文所想表达的坑,经过排查:
原文链接:父组件向子组件里的props动态传值出现错误提示的解决办法 - DCloud问答
既然找到问题,是因为延迟导致的,所以这里需要在父组件中加一个定时器来延迟触发,更改后的代码如下:
data() {return {confirm: false, // 此处只关注这个变量的传递,其他省略}
},
methods: {// 省略其他函数定义 ...submit(form) {this.confirm = true// 这样延迟触发,更改后的值就可以顺利传递到子组件中setTimeout(function () { this.$refs.loginRef.login() },1000)
}
简单记录一下,避免后面在遇到类似的问题!