为什么 sort 方法在父组件中不起作用?
Why the sort method not working in the parent component?
这是我在 VueJS 中的第一个项目。
我有一个产品列表,想按价格对其进行排序。我构建了两个组件并尝试通过发出事件将排序方法从子组件(下拉按钮)传递给父组件。但经过多次尝试,我找不到我的代码的错误,任何帮助!
此子组件:
<template>
<div class="dropdown">
<button
@click="toggleShow(); $emit('sortPrice')"
class="dropbtn"
>
{{ title }}
<span class="material-icons-outlined"> {{ icon }} </span>
</button>
<div v-if="showMenu" class="menu">
<div class="menu-item" v-for="(item, index) in this.items" :key="index">
{{ item }}
</div>
</div>
</div>
</template>
<script>
export default {
name: "Dropdown-menu",
props: {
title: String,
icon: String,
items: {
type: Object,
required: true,
},
},
data() {
return {
showMenu: false
};
},
methods: {
toggleShow: function () {
this.showMenu = !this.showMenu;
},
sortPrice: function () {
this.$emit("sort", this.sortPrice);
},
},
};
</script>
这个父组件:
<template>
<dropdown
:title="sortedBy"
:items="arrangements"
:icon="material_icons"
@sort="sortByPrice"
></dropdown>
</template>
<script>
import Dropdown from "@/components/Dropdown.vue";
export default {
components: {
Dropdown,
},
data() {
return {
sortedBy: "Featured",
arrangements: ["Featured", "Lowest", "Highest"],
material_icons: "expand_more",
productData: require("@/data/store-data.json"),
};
},
methods: {
sortByPrice: function () {
let realProducts = this.productData.products;
let sortedProducts = realProducts.sort((a, b) => {
if (this.sortedBy === "Highest") {
return b.price - a.price;
} else if (this.sortedBy === "Lowest") {
return a.price - b.price;
}
});
return sortedProducts;
},
},
};
</script>
建议:
- 在单击 dividual 项目时发出,而不是在单击按钮时发出。你想在用户做出选择时发出
- 所以这意味着通过
@click="sortPrice(item)"
从 menu-item div 调用 sortPrice 函数
- 然后在 sortPrice 函数中,传入项目参数
function (item) {
并将其作为第二个参数传递给您的 emit 调用:this.$emit("sort", item);
。家长必须知道选择了什么
- 在父组件sortByPrice函数中,接受item参数,
sortByPrice: function (item) {
并用它来设置sortedBy属性:this.sortedBy = item;
- 在随后显示的计算 属性 中进行排序,在我的示例中称为
sortedProducts
。
例如,家长:
<template>
<h2>Main App</h2>
<dropdown
:title="sortedBy"
:items="arrangements"
@sort="sortByPrice"
></dropdown>
<div>
<h3>Products</h3>
<ul>
<li v-for="product in sortedProducts" :key="product.index">
{{ product.name }} ${{ product.price }}
</li>
</ul>
</div>
</template>
<script>
import Dropdown from "@/components/Dropdown.vue";
export default {
components: {
Dropdown,
},
data() {
return {
sortedBy: "Featured",
arrangements: ["Featured", "Lowest", "Highest"],
productData: {
// dummy data for demo purposes
products: [
{ index: 1, name: "product A", price: 1, featured: true },
{ index: 2, name: "product B", price: 2, featured: false },
{ index: 3, name: "product C", price: 6, featured: true },
{ index: 4, name: "product G", price: 4, featured: false },
{ index: 5, name: "product V", price: 0, featured: true },
],
},
};
},
methods: {
sortByPrice: function (item) {
this.sortedBy = item;
},
},
computed: {
sortedProducts: function () {
if (this.sortedBy === "Featured") {
return this.productData.products.filter((prod) => prod.featured);
} else if (this.sortedBy === "Highest") {
return this.productData.products.sort((a, b) => b.price - a.price);
} else if (this.sortedBy === "Lowest") {
return this.productData.products.sort((a, b) => a.price - b.price);
}
// the "just-in-case" default return
return this.productData.products;
},
},
};
</script>
和子 Dropdown.vue 组件:
<template>
<div class="dropdown">
<button @click="toggleShow()" class="dropbtn">
{{ title }}
</button>
<div v-if="showMenu" class="menu">
<div
class="menu-item"
v-for="(item, index) in this.items"
:key="index"
@click="sortPrice(item)"
>
{{ item }}
</div>
</div>
</div>
</template>
<script>
export default {
name: "Dropdown-menu",
props: {
title: String,
items: {
type: Object,
required: true,
},
},
data() {
return {
showMenu: false,
};
},
methods: {
toggleShow: function () {
this.showMenu = !this.showMenu;
},
sortPrice: function (item) {
this.$emit("sort", item);
this.toggleShow();
},
},
};
</script>
这是我在 VueJS 中的第一个项目。 我有一个产品列表,想按价格对其进行排序。我构建了两个组件并尝试通过发出事件将排序方法从子组件(下拉按钮)传递给父组件。但经过多次尝试,我找不到我的代码的错误,任何帮助!
此子组件:
<template>
<div class="dropdown">
<button
@click="toggleShow(); $emit('sortPrice')"
class="dropbtn"
>
{{ title }}
<span class="material-icons-outlined"> {{ icon }} </span>
</button>
<div v-if="showMenu" class="menu">
<div class="menu-item" v-for="(item, index) in this.items" :key="index">
{{ item }}
</div>
</div>
</div>
</template>
<script>
export default {
name: "Dropdown-menu",
props: {
title: String,
icon: String,
items: {
type: Object,
required: true,
},
},
data() {
return {
showMenu: false
};
},
methods: {
toggleShow: function () {
this.showMenu = !this.showMenu;
},
sortPrice: function () {
this.$emit("sort", this.sortPrice);
},
},
};
</script>
这个父组件:
<template>
<dropdown
:title="sortedBy"
:items="arrangements"
:icon="material_icons"
@sort="sortByPrice"
></dropdown>
</template>
<script>
import Dropdown from "@/components/Dropdown.vue";
export default {
components: {
Dropdown,
},
data() {
return {
sortedBy: "Featured",
arrangements: ["Featured", "Lowest", "Highest"],
material_icons: "expand_more",
productData: require("@/data/store-data.json"),
};
},
methods: {
sortByPrice: function () {
let realProducts = this.productData.products;
let sortedProducts = realProducts.sort((a, b) => {
if (this.sortedBy === "Highest") {
return b.price - a.price;
} else if (this.sortedBy === "Lowest") {
return a.price - b.price;
}
});
return sortedProducts;
},
},
};
</script>
建议:
- 在单击 dividual 项目时发出,而不是在单击按钮时发出。你想在用户做出选择时发出
- 所以这意味着通过
@click="sortPrice(item)"
从 menu-item div 调用 sortPrice 函数
- 然后在 sortPrice 函数中,传入项目参数
function (item) {
并将其作为第二个参数传递给您的 emit 调用:this.$emit("sort", item);
。家长必须知道选择了什么 - 在父组件sortByPrice函数中,接受item参数,
sortByPrice: function (item) {
并用它来设置sortedBy属性:this.sortedBy = item;
- 在随后显示的计算 属性 中进行排序,在我的示例中称为
sortedProducts
。
例如,家长:
<template>
<h2>Main App</h2>
<dropdown
:title="sortedBy"
:items="arrangements"
@sort="sortByPrice"
></dropdown>
<div>
<h3>Products</h3>
<ul>
<li v-for="product in sortedProducts" :key="product.index">
{{ product.name }} ${{ product.price }}
</li>
</ul>
</div>
</template>
<script>
import Dropdown from "@/components/Dropdown.vue";
export default {
components: {
Dropdown,
},
data() {
return {
sortedBy: "Featured",
arrangements: ["Featured", "Lowest", "Highest"],
productData: {
// dummy data for demo purposes
products: [
{ index: 1, name: "product A", price: 1, featured: true },
{ index: 2, name: "product B", price: 2, featured: false },
{ index: 3, name: "product C", price: 6, featured: true },
{ index: 4, name: "product G", price: 4, featured: false },
{ index: 5, name: "product V", price: 0, featured: true },
],
},
};
},
methods: {
sortByPrice: function (item) {
this.sortedBy = item;
},
},
computed: {
sortedProducts: function () {
if (this.sortedBy === "Featured") {
return this.productData.products.filter((prod) => prod.featured);
} else if (this.sortedBy === "Highest") {
return this.productData.products.sort((a, b) => b.price - a.price);
} else if (this.sortedBy === "Lowest") {
return this.productData.products.sort((a, b) => a.price - b.price);
}
// the "just-in-case" default return
return this.productData.products;
},
},
};
</script>
和子 Dropdown.vue 组件:
<template>
<div class="dropdown">
<button @click="toggleShow()" class="dropbtn">
{{ title }}
</button>
<div v-if="showMenu" class="menu">
<div
class="menu-item"
v-for="(item, index) in this.items"
:key="index"
@click="sortPrice(item)"
>
{{ item }}
</div>
</div>
</div>
</template>
<script>
export default {
name: "Dropdown-menu",
props: {
title: String,
items: {
type: Object,
required: true,
},
},
data() {
return {
showMenu: false,
};
},
methods: {
toggleShow: function () {
this.showMenu = !this.showMenu;
},
sortPrice: function (item) {
this.$emit("sort", item);
this.toggleShow();
},
},
};
</script>