在 v-if 语句中使用三元表达式会在 Vue JS 中出错
Using ternary expression along v-if statement is giving errors in Vue JS
代码:-
<template>
<div id="calendars-results">
<div class="vs-con-loading__container">
<div class="vs-row flex justify-between">
<h4 class="vs-row mb-2">{{ title }}</h4>
<!-- Date Picker to change date -->
<date-picker
v-if="date"
class="vs-row"
v-model="date"
type="date"
placeholder="Select Date"
valueType="format"
format="YYYY-MM-DD"
@change="changeDate"
></date-picker>
</div>
<div v-if="total >= data_array.length" class="results-count mt-4">
Showing {{ data_array.length }} of {{ total }} Results
</div>
<!-- Table with Data -->
<div
v-if="data_array.length > 0"
class="earning-calendar overflow-x-scroll"
// If I remove the line below, the code works fine
:class = "[ title === "Earnings Calendar" && reduceButton === false ? "earning-calendar" : '']"
>
<div>SideBar docked = {{ !reduceButton }}</div>
<!-- Table with Data -->
<ticker-table
v-if="data_array.length > 0"
:stocks_clickable="stocks_clickable"
:data_array="data_array"
:data_headers="data_headers"
:sort_col_index="sort_col_index"
></ticker-table>
</div>
<h5 v-else-if="!loading" class="py-8 text-primary text-center">
<vs-icon
class="text-xl pr-2"
icon="icon-info"
icon-pack="feather"
></vs-icon>
<span>{{ no_results_msg }}</span>
</h5>
</div>
<div v-if="load_more_button" class="text-center">
<vs-button class="mt-6" @click="showMore">{{ show_more_text }}</vs-button>
</div>
<div
v-else-if="data_array.length > 0 && data_array.length > 20"
class="text-center"
>
<vs-button class="mt-6" @click="showLess">Show Less</vs-button>
</div>
</div>
</template>
<script>
import DatePicker from "vue2-datepicker";
import "vue2-datepicker/index.css";
import TickerTable from "@/components/shared/tables/ThTickerTable.vue";
export default {
name: "IPOEarnings",
components: {
DatePicker,
TickerTable
},
data() {
return {
sort_index: this.sort_col_index,
date: null,
loading: false
};
},
props: {
title: {
type: String,
required: true
},
no_results_msg: {
type: String,
required: true
},
default_date: {
type: String
},
data_array: {
type: Array,
required: true
},
data_headers: {
type: Array,
required: true
},
sort_col_index: {
type: Number,
required: true
},
stocks_clickable: {
type: Boolean,
default: false
},
load_more_button: {
type: Boolean,
default: false
},
show_more_text: {
type: String,
default: ""
},
total: {
type: Number,
default: 0
}
},
watch: {
data_array(oldVal, newVal) {
this.loading = false;
this.$vs.loading.close("#calendars-results > .con-vs-loading");
}
},
methods: {
changeDate(currentValue) {
this.loading = true;
this.$vs.loading({ container: "#calendars-results", scale: 0.6 });
this.date = currentValue;
// harcoded max 200 limit to get results
this.$emit("update", currentValue, 200);
},
showMore() {
this.$emit("showMore");
},
showLess() {
this.$emit("showLess");
}
},
created() {
this.loading = true;
this.date = this.default_date;
},
computed: {
reduceButton: {
get() {
return this.$store.state.reduceButton;
},
set(val) {
this.$store.commit("TOGGLE_REDUCE_BUTTON", val);
}
}
}
};
</script>
<style lang="scss">
@media (min-width: 1015px) {
.earning-calendar {
overflow: hidden !important;
}
}
</style>
错误
(Emitted value instead of an instance of Error)
Errors compiling template:
v-else-if="!loading" used on element <h5> without corresponding v-if.
37 | ></ticker-table>
38 | </div>
39 | <h5 v-else-if="!loading" class="py-8 text-primary text-center">
| ^^^^^^^^^^^^^^^^^^^^
40 | <vs-icon
41 | class="text-xl pr-2"
Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.
46 | </h5>
47 | </div>
48 | <div v-if="load_more_button" class="text-center">
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
49 | <vs-button class="mt-6" @click="showMore">{{ show_more_text }}</vs-button>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
50 | </div>
| ^^^^^^^^
51 | <div
| ^^^^^^
52 | v-else-if="data_array.length > 0 && data_array.length > 20"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
53 | class="text-center"
| ^^^^^^^^^^^^^^^^^^^^^^^
54 | >
| ^^^
55 | <vs-button class="mt-6" @click="showLess">Show Less</vs-button>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
56 | </div>
| ^^^^^^^^
57 | </div>
| ^^^^^^
如果我删除执行三元运算的行 :class = "[ title === "Earnings Calendar" && reduceButton === false ? "earning-calendar" : '']"
,那么代码可以正常工作。为什么 :class
和 v-if
中的三元运算符不能一起工作?有没有办法可以一起使用它们。我尝试将 v-if
更改为 v-else
,但错误仍然没有得到解决。但是如果我删除三元线,错误就会消失。究竟是什么导致了这里的错误?
改成这个
:class="{ 'earning-calendar' : title === 'Earnings Calendar' && reduceButton === false }"
问题是由于 class
绑定的双引号属性值中的嵌套双引号导致引号匹配失败:
outer
:class="[
title === "Earnings Calendar" && reduceButton === false ? "earning-calendar" : ''
]" inner inner inner inner
outer
快速解决方法是将内引号更改为单引号:
:class="[
title === 'Earnings Calendar' && reduceButton === false ? 'earning-calendar' : ''
]"
另请注意,您正在应用 earning-calendar
class 两次(一次是静态的,然后在 class 绑定中再次应用):
class="earning-calendar overflow-x-scroll"
^^^^^^^^^^^^^^^^
:class="[
title === 'Earnings Calendar' && reduceButton === false ? 'earning-calendar' : ''
]" ^^^^^^^^^^^^^^^^
您或许应该删除静态 class 名称,或更新动态名称。
但更 succinct/readable 的解决方案是使用 object syntax of class bindings, as shown in the .
代码:-
<template>
<div id="calendars-results">
<div class="vs-con-loading__container">
<div class="vs-row flex justify-between">
<h4 class="vs-row mb-2">{{ title }}</h4>
<!-- Date Picker to change date -->
<date-picker
v-if="date"
class="vs-row"
v-model="date"
type="date"
placeholder="Select Date"
valueType="format"
format="YYYY-MM-DD"
@change="changeDate"
></date-picker>
</div>
<div v-if="total >= data_array.length" class="results-count mt-4">
Showing {{ data_array.length }} of {{ total }} Results
</div>
<!-- Table with Data -->
<div
v-if="data_array.length > 0"
class="earning-calendar overflow-x-scroll"
// If I remove the line below, the code works fine
:class = "[ title === "Earnings Calendar" && reduceButton === false ? "earning-calendar" : '']"
>
<div>SideBar docked = {{ !reduceButton }}</div>
<!-- Table with Data -->
<ticker-table
v-if="data_array.length > 0"
:stocks_clickable="stocks_clickable"
:data_array="data_array"
:data_headers="data_headers"
:sort_col_index="sort_col_index"
></ticker-table>
</div>
<h5 v-else-if="!loading" class="py-8 text-primary text-center">
<vs-icon
class="text-xl pr-2"
icon="icon-info"
icon-pack="feather"
></vs-icon>
<span>{{ no_results_msg }}</span>
</h5>
</div>
<div v-if="load_more_button" class="text-center">
<vs-button class="mt-6" @click="showMore">{{ show_more_text }}</vs-button>
</div>
<div
v-else-if="data_array.length > 0 && data_array.length > 20"
class="text-center"
>
<vs-button class="mt-6" @click="showLess">Show Less</vs-button>
</div>
</div>
</template>
<script>
import DatePicker from "vue2-datepicker";
import "vue2-datepicker/index.css";
import TickerTable from "@/components/shared/tables/ThTickerTable.vue";
export default {
name: "IPOEarnings",
components: {
DatePicker,
TickerTable
},
data() {
return {
sort_index: this.sort_col_index,
date: null,
loading: false
};
},
props: {
title: {
type: String,
required: true
},
no_results_msg: {
type: String,
required: true
},
default_date: {
type: String
},
data_array: {
type: Array,
required: true
},
data_headers: {
type: Array,
required: true
},
sort_col_index: {
type: Number,
required: true
},
stocks_clickable: {
type: Boolean,
default: false
},
load_more_button: {
type: Boolean,
default: false
},
show_more_text: {
type: String,
default: ""
},
total: {
type: Number,
default: 0
}
},
watch: {
data_array(oldVal, newVal) {
this.loading = false;
this.$vs.loading.close("#calendars-results > .con-vs-loading");
}
},
methods: {
changeDate(currentValue) {
this.loading = true;
this.$vs.loading({ container: "#calendars-results", scale: 0.6 });
this.date = currentValue;
// harcoded max 200 limit to get results
this.$emit("update", currentValue, 200);
},
showMore() {
this.$emit("showMore");
},
showLess() {
this.$emit("showLess");
}
},
created() {
this.loading = true;
this.date = this.default_date;
},
computed: {
reduceButton: {
get() {
return this.$store.state.reduceButton;
},
set(val) {
this.$store.commit("TOGGLE_REDUCE_BUTTON", val);
}
}
}
};
</script>
<style lang="scss">
@media (min-width: 1015px) {
.earning-calendar {
overflow: hidden !important;
}
}
</style>
错误
(Emitted value instead of an instance of Error)
Errors compiling template:
v-else-if="!loading" used on element <h5> without corresponding v-if.
37 | ></ticker-table>
38 | </div>
39 | <h5 v-else-if="!loading" class="py-8 text-primary text-center">
| ^^^^^^^^^^^^^^^^^^^^
40 | <vs-icon
41 | class="text-xl pr-2"
Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.
46 | </h5>
47 | </div>
48 | <div v-if="load_more_button" class="text-center">
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
49 | <vs-button class="mt-6" @click="showMore">{{ show_more_text }}</vs-button>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
50 | </div>
| ^^^^^^^^
51 | <div
| ^^^^^^
52 | v-else-if="data_array.length > 0 && data_array.length > 20"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
53 | class="text-center"
| ^^^^^^^^^^^^^^^^^^^^^^^
54 | >
| ^^^
55 | <vs-button class="mt-6" @click="showLess">Show Less</vs-button>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
56 | </div>
| ^^^^^^^^
57 | </div>
| ^^^^^^
如果我删除执行三元运算的行 :class = "[ title === "Earnings Calendar" && reduceButton === false ? "earning-calendar" : '']"
,那么代码可以正常工作。为什么 :class
和 v-if
中的三元运算符不能一起工作?有没有办法可以一起使用它们。我尝试将 v-if
更改为 v-else
,但错误仍然没有得到解决。但是如果我删除三元线,错误就会消失。究竟是什么导致了这里的错误?
改成这个
:class="{ 'earning-calendar' : title === 'Earnings Calendar' && reduceButton === false }"
问题是由于 class
绑定的双引号属性值中的嵌套双引号导致引号匹配失败:
outer
:class="[
title === "Earnings Calendar" && reduceButton === false ? "earning-calendar" : ''
]" inner inner inner inner
outer
快速解决方法是将内引号更改为单引号:
:class="[
title === 'Earnings Calendar' && reduceButton === false ? 'earning-calendar' : ''
]"
另请注意,您正在应用 earning-calendar
class 两次(一次是静态的,然后在 class 绑定中再次应用):
class="earning-calendar overflow-x-scroll"
^^^^^^^^^^^^^^^^
:class="[
title === 'Earnings Calendar' && reduceButton === false ? 'earning-calendar' : ''
]" ^^^^^^^^^^^^^^^^
您或许应该删除静态 class 名称,或更新动态名称。
但更 succinct/readable 的解决方案是使用 object syntax of class bindings, as shown in the