“Reactive Prop Input Vue3” 可以翻译为 “响应式属性输入 Vue3″。

huangapple go评论75阅读模式
英文:

Reactive Prop Input Vue3

问题

解释

我有一个父组件和一个子组件。

子组件是使用v-for='course in allCourses'创建的,循环遍历一个对象数组。
它通过props接收一个名为isSelected的布尔值。

isSelected布尔值取决于子组件的相应课程是否包含在另一个数组中:const selectedCourses = ref<Array<Object>>()

为了检查这一点,我实现了一个箭头函数,如下所示:

const isSelected = (_courseData :any) :boolean => {
    if (selectedCourses.value?.some(e => e == _courseData)) {
        return true
    }
    else {
        return false
    }
}

我将这个函数添加到了子组件的prop中,如下所示:

<mychildcomponent v-for="course in allCourses" :isSelected="isSelected(course)" @toggle-select="handleSelect"/>

问题

然而,当对selectedCourses数组进行更改时,当然不会更新,因为我在子组件中通过emit进行了更改。

当子组件被点击时,如果现在被选中,它会发出它的数据,如果现在未选中,它只会发出false。父组件内有一个简单的函数来处理这个操作,要么将数据推送到selectedCourses,要么将其删除。

问题

当这个emit触发时(或者可能是通过hook来更新selectedCourses时),如何让我的isSelected函数运行(从而更新每个子组件的isSelected prop)?
我知道我可以将整个selectedCourses作为prop传递给子组件,并在其中评估其状态,但我不想这样做以确保prop的稳定性。

英文:

Explanation

I have a parent and a child component.

The child component is created using v-for=&#39;course in allCourses&#39;, cycling through an array of objects.
It receives a bool called isSelected via props.

The isSelected bool depends on if the respective course of the child component is contained in another array: const selectedCourses = ref&lt;Array&lt;Object&gt;&gt;()

To check for this i implemented an arrow function that looks like this:

const isSelected = (_courseData :any) :boolean =&gt; {
    if (selectedCourses.value?.some(e =&gt; e == _courseData)) {
        return true
    }
    else {
        return false
    }
}

This i added into the prop of my child component as follows:

&lt;mychildcomponent v-for=&quot;course in allCourses&quot; :isSelected=&quot;isSelected(course)&quot; @toggle-select=&quot;handleSelect&quot;/&gt;

Problem

However, of course, this does not update when there are changes made to the selectedCourses-Array, as i do via an emit in my child component.

When the child is clicked, it emits its data if its now selected or just false if it's now unselected. A simple function handles this inside my parent component to either push the data to selectedCourses or remove it.

Question

How do i get my isSelected-function to run (and therefore update the isSelected-prop of each child component) when this emit fires (or maybe with a hook for when selectedCourses is updated)?
I know i could just pass in the whole selectedCourses as a prop into my child component and evaluate it's state in there, however i do not want to do this to ensure prop stability.

答案1

得分: 0

解决方案沿着Dimavas在他的评论中提出的方向前进。

但我需要做一些额外的工作,以使其适应我的需求。

@toggle-select="isSelected($event, true)" :isSelected='isSelected(course, false)'

组件现在触发isSelected()。事件包含了发射的数据,我还传入true作为第二个参数。

isSelected看起来像这样:

const isSelected = (_courseData: any, _update: boolean): boolean => {
if (_update) {
handleSelect(_courseData)
}
if (selectedCourses.value?.some((e: any) => e == _courseData)) {
return true
}
else {
return false
}
}

我们之前传入的_update布尔值是为了阻止这个解决方案进入无限循环,因为isSelected()也在我的组件的isSelected属性中调用。在那里,我们传入false来阻止递归。

英文:

The solution goes into the direction of Dimavas proposal in his comment.

I had to do a little more though to make it fit for my needs.

@toggle-select=&quot;isSelected($event, true)&quot; :isSelected=&#39;isSelected(course, false)&#39;

The components emit now executes isSelected(). The event contains the data of the emit, also i pass in true as a second argument.

isSelected looks like this:

const isSelected = (_courseData :any, _update: boolean) :boolean =&gt; {
    if(_update) {
        handleSelect(_courseData)
    }
    if (selectedCourses.value?.some((e: any) =&gt; e == _courseData)) {

        return true
    }
    else {
        return false
    }
}

The _update-Bool we passed in earlier is there to stop this solution from entering an infinite loop, as isSelected() is also called in the isSelected-prop of my component. There we pass in false to stop the recursion.

huangapple
  • 本文由 发表于 2023年6月15日 18:40:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76481679.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定