我有一个简单的组件,比如Transaction.vue,在它里面有一个名为TransactionEditModal.vue的子组件。
在Transaction. vue组件中,我通过单击按钮调用方法"openTransactionEditModal",方法的流程是,在使用"showModal()"打开模态之前,我首先编辑我的子属性"this. chosenTransactionId"。
// Transaction.vue
<button ref="editTransactionButton" v-on:click="openTransactionEditModal($event)" class="btn btn-primary">
<i style="pointer-events: none" class="far fa-edit"></i>
</button>
<TransactionEditModal ref="transactionEditModal" v-bind:transactionId="chosenTransactionId" />
<script>
data: function () {
return {
chosenTransactionId: "",
}
}
methods: {
openTransactionEditModal(event: MouseEvent) {
if (event.currentTarget instanceof HTMLButtonElement) {
this.chosenTransactionId = event.currentTarget.id;
console.log("Chosen Transaction Id is Updated", event.currentTarget.id);
}
var transactionEditModal: any = this.$refs.transactionEditModal; transactionEditModal.initializeExistingValues(this.transactions[6]);
transactionEditModal.showModal();
}
}
</script>
// TransactionEditModal.vue
<script>
props: {
transactionId: String,
},
methods: {
showModal() {
console.log("Child component props should have been updated, is it? ", this.transactionId);
var reportApproveModal: JQuery<HTMLDivElement> = $('#transactionEditModal');
reportApproveModal.modal('show');
},
}
</script>
但是为什么 prop 只有在第二次点击后才更新呢?
结果:
一个二个一个一个
更新1
在子组件中使用监视功能后,我得到以下结果:
Chosen Transaction Id is Updated 5aa1dfc7-4b2f-4dbe-911f-98d70a2624f2 Transaction.vue:365
Child component props should have been updated, is it? TransactionEditModal.vue:36
Means updated after watch 5aa1dfc7-4b2f-4dbe-911f-98d70a2624f2 TransactionEditModal.vue:42
我推断它是在调用showModal()之后更新的,我实际上发现这很奇怪,也许更新 prop 是异步的?
// TransactionEdit.vue
<script>
watch: {
transactionId(newVal, oldVal) {
console.log('Means updated after watch', newVal, oldVal);
},
},
</script>
2条答案
按热度按时间nnt7mjpx1#
之所以要在第二次点击后才更新props,是因为Vue使用了异步更新队列来更新组件,也就是说当你在
openTransactionEditModal
方法中更新props的时候,并不是立即生效,而是加入到更新队列中,在当前事件循环之后进行处理,当你第一次点击按钮的时候,更新props并添加到更新队列中,但是在更新之前调用了showModal
方法,所以子组件仍然有旧的props,第二次点击按钮时,更新已经被处理并且子组件现在具有更新的 prop 。使用子组件中的监视功能,您可以检查 prop 的更新值以及更新的确切时间。您可以重构代码以确保子组件在调用
showModal
方法之前接收到更新的props:我添加了一个自定义事件
'modal-open'
,它在更新chosenTransactionId后从父组件发出,并触发showModal()
方法。这样,我们可以确保子组件在打开模态之前已经接收到更新的props。此外,我还将
initializeExistingValues()
和$emit('modal-open')
函数 Package 在this.$nextTick(() =>{})
中,以确保在调用该函数之前已经更新了值。此外,我还删除了不必要的ref属性和HTMLButtonElement的类型转换。
wgmfuz8q2#
是否确定已设置正确的
transactionId
React?在
Transaction.vue
中,您定义了一个名为transactionId
的无功变量。但是在该组件的代码中,您引用了名为
chosenTransactionId
的变量。我建议您将其合理化为两者都只有
transactionId
。或者,如果您确实需要两个单独的变量,则将
chosenTransationId
添加到Transaction.vue
中的data
函数。一旦设置了
transactionId
,只允许modal存在怎么样?你可以改变
到
这是一种更传统的方法,你甚至可以用一个v-bind参数把初始化信息发送给子组件,这样父组件就不必直接调用Modal中的函数了。
一般来说,最好避免在子节点中调用函数的模式,相反,只有当所有必要的信息都可用并准备好传递给子节点时,才让子节点存在(使用
v-if
)。