Javascript 第二次单击后的Vue.js渲染
我有一个表单,它使用下拉菜单允许用户选择他们的配置,当他们单击Javascript 第二次单击后的Vue.js渲染,javascript,vue.js,Javascript,Vue.js,我有一个表单,它使用下拉菜单允许用户选择他们的配置,当他们单击apply时,将呈现一个highchart。乍一看,这是完美的 我的问题是,如果在呈现图表后,您再次打开下拉列表进行更改,而不关闭下拉列表,然后单击apply,我们将获得具有先前配置的图表。我必须再次单击apply,以显示新配置 我错过了什么 以下是完整代码的一部分: <template> <div class="dropdown multiple-select"> <Gl
apply
时,将呈现一个highchart。乍一看,这是完美的
我的问题是,如果在呈现图表后,您再次打开下拉列表进行更改,而不关闭下拉列表,然后单击apply
,我们将获得具有先前配置的图表。我必须再次单击apply
,以显示新配置
我错过了什么
以下是完整代码的一部分:
<template>
<div class="dropdown multiple-select">
<GlobalEvents v-if="open" @click="handleClick" @keydown.esc="close" />
<button
ref="button"
class="btn btn-block btn-multiple-select"
type="button"
:disabled="disabled"
@click="toggle"
>
<span v-if="internalValue.length === 0"> {{ emptyLabel }} </span>
<span v-else> {{ internalValue.length }} Selected </span>
<b-icon :icon="open | icon" :scale="0.5" />
</button>
<div ref="dropdown" class="dropdown-menu" :class="{ show: open }">
<template v-if="!loading">
<div class="px-4 pt-1">
<div class="form-group">
<b-form-input
v-model="search"
debounce="500"
placeholder="Search"
/>
</div>
</div>
<div class="scroll px-4">
<b-form-checkbox v-model="selectAll" class="py-1" @change="toggleAll">
Select all
</b-form-checkbox>
<b-form-checkbox
v-for="item in filtered"
:key="item.id"
v-model="internalValue"
:value="item"
class="py-1"
@input="checkSelectAllStatus"
>
{{ item.name }}
</b-form-checkbox>
<p v-if="filtered.length === 0">No results.</p>
</div>
</template>
<div v-else class="text-center my-2">
<b-spinner />
</div>
</div>
</div>
</template>
<script>
import { createPopper } from '@popperjs/core';
import GlobalEvents from 'vue-global-events';
export default {
components: {
GlobalEvents
},
filters: {
icon(item) {
return item ? 'caret-up-fill' : 'caret-down-fill';
}
},
model: {
prop: 'value',
event: 'change'
},
props: {
emptyLabel: {
type: String,
default: () => 'None Selected'
},
disabled: {
type: Boolean,
default: () => false
},
loading: {
type: Boolean,
default: () => false
},
options: {
type: Array,
default: () => []
},
value: {
type: Array,
default: () => []
}
},
data() {
return {
internalValue: this.value,
open: false,
popper: null,
search: '',
selectAll: false
};
},
computed: {
filtered() {
return this.options.filter((item) =>
item.name.toLowerCase().includes(this.search.toLowerCase())
);
},
showAll() {
return (
this.internalValue.length > 0 &&
this.internalValue.length === this.options.length
);
}
},
watch: {
options() {
this.checkSelectAllStatus();
},
internalValue() {
this.checkSelectAllStatus();
},
value(value) {
this.internalValue = value;
this.$emit('change', this.internalValue);
}
},
methods: {
checkSelectAllStatus() {
this.selectAll = this.internalValue.length === this.options.length;
},
close() {
this.open = false;
this.search = '';
this.$emit('change', this.internalValue);
},
create() {
this.popper = createPopper(this.$refs.button, this.$refs.dropdown, {
placement: 'bottom-start',
modifiers: [
{
name: 'offset',
options: {
offset: [0, 10]
}
}
]
});
},
destroy() {
if (this.popper) {
this.popper.destroy();
this.popper = null;
}
},
handleClick(event) {
if (!this.$el.contains(event.target)) {
this.close();
}
},
toggle() {
this.open = !this.open;
if (this.open) {
this.$emit('open');
this.create();
} else {
this.destroy();
}
},
toggleAll(checked) {
if (checked) {
this.internalValue = this.options;
} else {
this.internalValue = [];
}
}
}
};
</script>
{{emptyLabel}}
{{internalValue.length}}已选定
全选
{{item.name}
没有结果
从“@popperjs/core”导入{createPopper};
从“vue全局事件”导入全局事件;
导出默认值{
组成部分:{
全球事件
},
过滤器:{
图标(项目){
返回项目?'caret up fill':'caret down fill';
}
},
型号:{
道具:“价值”,
事件:“更改”
},
道具:{
空标签:{
类型:字符串,
默认值:()=>“未选择”
},
残疾人士:{
类型:布尔型,
默认值:()=>false
},
装载:{
类型:布尔型,
默认值:()=>false
},
选项:{
类型:数组,
默认值:()=>[]
},
价值:{
类型:数组,
默认值:()=>[]
}
},
数据(){
返回{
内在价值:这个价值,
开:错,
波普尔:空,
搜索:“”,
selectAll:false
};
},
计算:{
过滤的(){
返回此.options.filter((项)=>
item.name.toLowerCase().includes(this.search.toLowerCase())
);
},
showAll(){
返回(
this.internalValue.length>0&&
this.internalValue.length==this.options.length
);
}
},
观察:{
选项(){
选中此选项。选中SelectAllStatus();
},
内部价值(){
选中此选项。选中SelectAllStatus();
},
价值(价值){
这个值=值;
此.emit('change',此.internalValue);
}
},
方法:{
选中SelectAllStatus(){
this.selectAll=this.internalValue.length==this.options.length;
},
关闭(){
this.open=false;
this.search='';
此.emit('change',此.internalValue);
},
创建(){
this.popper=createPopper(this.$refs.button,this.$refs.dropdown{
位置:'底部开始',
修改器:[
{
名称:“偏移量”,
选项:{
偏移量:[0,10]
}
}
]
});
},
销毁{
如果(这个波普尔){
这个.popper.destroy();
this.popper=null;
}
},
handleClick(事件){
如果(!this.$el.contains(event.target)){
这个。关闭();
}
},
切换(){
this.open=!this.open;
如果(这个打开){
这是。$emit('open');
这个。create();
}否则{
这个。销毁();
}
},
toggleAll(选中){
如果(选中){
this.internalValue=this.options;
}否则{
this.internalValue=[];
}
}
}
};
您似乎在使用vuelidate—您没有直接访问表单值,而是通过验证模型,这有什么好的理由吗
在不了解配置的情况下,您的代码应该更像这样:
async apply() {
try {
this.chartOptions.utilityMetric = this.form.metric;
this.chartOptions.title = this.getTitle();
this.loading = true;
this.$v.$touch()
if (this.$v.$error) throw new Error('form not valid')
const response = await await this.$api.organizations.getAnnualWidget(
this.organizationId,
this.parentUtility,
this.requestParams
);
this.chartOptions.categories = response.data.categories;
this.chartOptions.series = response.data.series;
this.chartOptions.yAxis = response.data.yAxis;
this.$forceUpdate();
} catch (error) {
const message = getErrorMessage(error);
this.$bvToast.toast(message, {
title: 'Error',
toaster: 'b-toaster-top-center',
variant: 'danger'
});
} finally {
this.loading = false;
}
}
及
同样,在不知道完整代码的情况下,很难判断,但我猜是指向vuelidate导致了这些问题找到了一个与我们现有解决方案兼容的解决方案。我的
MultipleSelect
组件正在调用@input=“checkSelectAllStatus”
我添加了
this.$emit('change',this.internalValue)
到选中selectallstatus
方法,它就工作了。谢谢你的回答,它没有解决我的问题。我已经用完整的代码更新了我的问题。再次感谢,希望这能有所帮助。
requestParams() {
return {
calendarization: this.form.calendarization,
metrics: this.form.metric.map((metric) => metric.id),
meterIds: this.form.meterIds,
Years: this.form.fiscalYears.map((year) => year.value),
waterType: this.form.waterType,
includeBaseline: this.form.baseLine,
showDataLabels: this.form.showDataLabels
};
},