单击 'Select all options' 时 Vue3 CoreUI CMultiSelect 无意中提交

Vue3 CoreUI CMultiSelect submitting unintentionally when 'Select all options' is clicked

我对 Vue.js (3) 中的编码还很陌生,我参与的项目使用 CoreUI for Vue 作为表单和显示的主要框架。我不确定这是否是 CoreUI CMultiSelect 本身的错误,但是当用户在其中一个表单下拉列表中单击 'Select all options' 时,表单会在用户之前自动提交可以自己填rest/submit吧。我特别困惑,因为即使我将组件与定义为保存其 selection 的自定义 @change(我刚刚删除了该行)断开连接,它仍然会显示问题。任何帮助将不胜感激!

旁注:我也不熟悉如何禁用 select-all 选项,尽管它提到这在 CoreUI Vue MultiSelect Documentation 中是可能的。我在组件中设置了 select-all="false" 没有用。如果这是我暂时必须做的事情,直到我弄清楚,我将不胜感激关于如何做的指导。

这里是组分和select离子选项:

<CMultiSelect
  placeholder="Application Types"
  :options="battery_application_choices"
  @change="batteryappChanged($event)"
>

<!-- inside data() -->
battery_application_choices: [
  { text: 'Demand Reduction', value: 'Demand Reduction' },
  { text: 'Energy Arbitrage', value: 'Energy Arbitrage' },
  { text: 'Frequency Response', value: 'Frequency Response' },
  { text: 'Microgrid Component', value: 'Microgrid Component' },
  { text: 'Other', value: 'Other' },
  { text: 'Solar / Storage', value: 'Solar / Storage' },
  { text: 'UPS', value: 'UPS' },
],

Select All Bug. I am not performing any other action besides clicking the 'Select all options' button

我自己的回答,因为有时编码就是这样。

1) 临时修复

我找到了如何实施我的临时修复,我需要输入带冒号的 :select-all="false" 来绑定它而不是 select-all="false"。对于像我这样的新手,: 是 Vue 中 v-bind 的缩写,它将数据绑定到组件,以便当数据发生变化时,应用程序的状态也会发生变化以反映它。

几天后...
2) 稳健修复

为了描述这个问题的可靠解决方案,我将概述我学到的关于 JS 事件的知识以及 Vue 如何处理观察它们及其传播。我还将介绍一些 Vue 如何使用您编写的内容来生成 HTML 代码,特别是 CoreUI 多选组件如何生成 HTML 元素,如 <select><options>

导致错误的原因是 <CMultiSelect> 嵌套在父 <CForm> 中。这本身并不是一个坏习惯,而且考虑到某些表单在其他表单字段旁边应该有多个选择字段,甚至是实用的。但是,当用户单击 'Select all options' 按钮时出现问题。这是因为将 <CMultiSelect> 放入您的代码中会指示 Vue 在运行时组成一组元素,这些元素是从您(开发人员)那里抽象出来的。 Vue 为每个绑定到 <CMultiSelect> 的选项生成一个 <select> 块,其中包含一个 <option> 元素。它还生成一个 'Select all options' <button>,由于某种原因可以生成 SubmitEvent。当这个事件产生时,它会向上传播,因为它没有被 event.preventDefault()event.stopPropagation() 停止。它被父 <CForm> 的提交观察者捕获并触发了我项目中的自定义表单提交。此行为也是由用于从多选视图中删除标签的小 x 按钮引起的,但我没有用 console.log() 仔细查看生成的代码以找出原因。

我通过检查 eventsubmitter 属性 解决了这个问题。

Side note: I would recommend doing a quick console.log(event) in any event handler methods that you are having trouble with, since events are much more complex than I thought and you will be able to see properties that can be of use to you.

event.submitter 是一个 属性 提交事件,returns 是生成该特定提交的 HTML 元素。在我的例子中,它返回 <CMultiSelect> 的 'submit(?)' 按钮,其形式为 <button ...>Select all options</button>。然后我只访问带有 event.submitter.innerHTML 的内容(只生成 Select all options),如果它与该内容匹配,则什么也不做。这也可以用于具有多个提交按钮的表单,这些按钮触发不同类型的提交(可能是用户数据的交替处理),因为它可以让你知道事件来自哪里。

例如下面的表格...
<form @submit.prevent="customHandler($event)">
    <button type='submit'>Save</button>
    <button type='submit'>Change</button>
</form>
...可以在其处理程序方法中具有以下控制逻辑:
customHandler(event) {
    if (event.submitter.innerHTML == 'Save') {
        // Save user data
    } else if (event.submitter.innerHTML == 'Change') {
        // Change user data in different way than 'Save'
    } else {
        // Do nothing
        // The CMultiSelect's 'Select all options' event will fall here
    } 
}
我们学到了什么?

由于这个问题占用了我大约 3 个工作日的工作时间,所以我认为我所做的 post 应该具有相同的重要性。我知道这是矫枉过正,但即使是其他开发人员也能避免同样的问题,那么这将是非常值得的。我会说我了解到 JavaScript 比我想象的要复杂得多,但同时又愚蠢得令人沮丧,但这意味着我以前不知道...