Bootstrap Vue 阻止/取消事件
Posted
技术标签:
【中文标题】Bootstrap Vue 阻止/取消事件【英文标题】:Bootstrap Vue prevent / cancel event 【发布时间】:2019-05-30 03:41:00 【问题描述】:我有一个带有来自 Bootstrap Vue 的 b-form-select 控件的页面。 当我更改此控件的值时,我想执行一个可能取消此事件的函数,而不是更改值。
为了让事情变得更复杂,我的选择在子组件中,而我执行的函数在父组件中。
子组件
public values: any[] = [
name: 'default',
name: 'forbidden',
name: 'other option' ,
]
<b-form-select :value="property" @change="$emit('onPropertyChange', arguments[0])">
<option v-for="(val, key) in values" :value="val" :key="key">val.Name</option>
</b-form-select>
父组件:
this.property = name: 'default'
public onPropertyChange(newValue)
if (newValue.name === 'forbidden')
// Not changing this.property
else
// Changing it
this.property = newValue
<child :property="property" @onPropertyChange="onPropertyChange"></child>
当我在选择中选择“禁止”时。我看到选择框已更改为该值,但子项中的属性以及父项中的属性仍然具有旧值,这就是我想要的。我怎样才能选择拥有旧值?
Bootstrap Vue 似乎没有更改事件的 prevent 修饰符。 我也尝试过使用本机事件,但也有同样的问题。
我是不是做错了什么?
【问题讨论】:
不知道<b-form-select>
是什么组件,但是常规选择使用v-model
绑定选择的值。
@thefallen 因为我从父母那里获得了属性,所以我不允许使用 v-model,因为您不应该在 Vue 中设置子级的属性
【参考方案1】:
与神秘地让它们不选择所选值相比,禁用禁用选项可能会更好的用户体验,但您可以通过保存旧值并将其恢复到 nextTick
在更改事件处理程序中获得该行为。
请注意,您的options
结构不适用于b-form-select
。我已经做了一个计算,它使正确的结构和句柄设置disabled
,并在b-form-select
中使用它。
new Vue(
el: '#app',
data:
selected: 'default',
options: [
name: 'default',
,
name: 'forbidden'
,
name: 'other option'
,
name: 'what I had before'
,
]
,
computed:
selectOptions()
return this.options.map((opt) => (
text: opt.name,
value: opt.name,
disabled: opt.name === 'forbidden'
));
,
methods:
onChange(newValue)
const oldValue = this.selected;
if (newValue === 'what I had before')
this.$nextTick(() =>
this.selected = oldValue;
);
);
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<script src="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>
<div id="app">
<b-form-select v-model="selected" :options="selectOptions" @change="onChange">
</b-form-select>
<div>Selected: <strong>selected</strong></div>
</div>
【讨论】:
感谢您的回复。禁用词只是我想将其设置为旧值的一个例子。在我的应用程序中,我会提示一个对话框,让用户确认他们想要进行一些更改。我会尝试你的建议在下一个滴答声中重置它。我只是想知道为什么选择没有取消或阻止选项 更改是原子的——这也适用于其他类型的输入小部件。它们没有“更新前”生命周期类型的方法。您可以确认用户意图,但没有确认用户交互。用户输入发生并且您对其做出响应。这就是它的设计方式。【参考方案2】:我想提出一个基于 $refs 和计算的 getter/setter 的解决方案(但它也可以通过 v-bind/v-on 来实现)。此类功能有有效的用例,例如要求用户确认。
<template>
<div>
<b-form-select
ref="mySelect"
v-model="choiceHandler"
:options="selectOptions"
>
</b-form-select>
</div>
</template>
<script>
export default
data()
return
selectOptions: [
value: 1, text: "Choice 1" ,
value: 2, text: "Choice 2" ,
value: 3, text: "Choice 3" ,
],
storedChoice: 3,
;
,
computed:
choiceHandler:
get()
return this.storedChoice;
,
set(newValue)
this.$refs.typeSelect.localValue = this.storedChoice; // this reverts displayed value to the one resulting from stored value
let confirmDialog = new Promise((resolve) =>
// this promise is a mockup for an asycnc dialog returning true / false
setTimeout(() =>
resolve(true);
, 1500);
);
confirmDialog.then((res) =>
if (res)
this.storedChoice = newValue;
else console.log("No changes");
);
,
,
,
;
</script>
我们需要使用setter
来防止用户更改被传递到数据模型/存储。在验证之前,我们将b-form-select
的localValue
设置为用户交互之前的值。如果验证是肯定的,我们更新数据模型中的值,这使得 Vue 刷新b-form-select
。如果没有,我们什么也不做。
此操作可能会触发Vue warning
直接操作 DOM(取决于您在此处所做的具体操作),但是我认为这是一个合理的使用,因为我们不会尝试显示覆盖我们的数据模型的数据 - 在相反 - 我们正在阻止浏览器显示尚未存储在模型中的数据。
您还可以使用 vanilla <select>
标签(不是 BootstrapVue - 它的工作方式略有不同)和 v-bind
/v-on
而不是 getter/setter 方法检查 here 我对同一问题的解决方案。
【讨论】:
以上是关于Bootstrap Vue 阻止/取消事件的主要内容,如果未能解决你的问题,请参考以下文章