我正在创建一个将在页面上显示产品的应用程序。这些产品中的每一个都有一个功能列表,例如“电池电量”,“充电时间”,甚至只是随功能而异的描述。我的问题是,如何制作可点击的元素,当单击该元素时将查找与该按钮/图标关联的数据,然后更新页面上的内容以反映这一点?此内容可能会或可能不会出现在某种形式的v-for循环中。
在下面查看我所拥有和想要实现的示例。
子组件:
<template>
<li>
<button @click="$emit('changeProductData', feature)">
<img :src="require('../assets/images/' + feature.item.img)" />
</button>
</li>
</template>
<script>
export default {
props: {
feature: Object
}
}
</script>
父组件:
<template>
<div>
<div v-for="product in getProduct(productId)" :key="product.productId">
{{ product }}
<Halo
:featuresCount="
`circle-container-` + product.features.length.toString()
"
>
<Feature
v-for="(feature, key, index) in product.features"
:key="index"
:feature="feature"
@changeProductData="something" // this is where we call the custom event
></Feature>
</Halo>
<h1>This is where I want to dynamically inject the title for each feature on clicking corresponding feature</h1>
</div>
</div>
</template>
<script>
import Halo from '@/components/ProductHalo.vue'
import Feature from '@/components/ProductFeature.vue'
import json from '@/json/data.json'
export default {
name: 'ProductSingle',
components: {
Halo,
Feature
},
data() {
return {
products: json
}
},
computed: {
productId() {
return this.$route.params.id
}
},
methods: {
getProduct(id) {
let data = this.products
return data.filter(item => item.productId == id)
},
something(e) {
// ideally we have a method here that grabs the corresponding
//feature then displays it on the page
console.log(e.item.text)
}
}
}
</script>
我的console.log调用确实确实从data.json中调用了正确的标题,如下所示:
[
{
"productId": 1,
"name": "Test 1",
"image": "sample.jpg",
"features": [
{
"item": {
"text": "Something else",
"img": "sample.jpg"
}
},
{
"item": {
"text": "Turbo",
"img": "wine.jpg"
}
},
{
"item": {
"text": "Strong",
"img": "sample.jpg"
}
}
]
}
]
所以看来我可以根据每个相应项目的点击来访问我的标题,只是不确定如何在任意位置显示该标题!有什么神奇的Vue js专家可以解决这个难题? TIA
答案 0 :(得分:0)
选项1:更改子组件
我不是只为一个功能按钮创建组件,而是将整个功能列表嵌入到h1
组件中,以便在其中显示所选功能。因此,子组件将如下所示:
<template>
<div>
<li v-for="(feature, key, index) in features" :key="index">
<button @click="setFeature(feature)">
<img :src="require('../assets/images/' + feature.item.img)" />
</button>
</li>
<h1>{{ clickedFeuatureText }}</h1>
</div>
</template>
<script>
export default {
data() {
return {
clickedFeuatureText:null
}
},
methods: {
setFeature(e){
this.clickedFeuatureText = e.item.text
}
},
props: {
features: Array
}
}
</script>
这是具有相应更改的父组件:
<template>
<div>
<div v-for="product in getProduct(productId)" :key="product.productId">
{{ product }}
<Halo
:featuresCount="
`circle-container-` + product.features.length.toString()
"
>
<Feature :features=" product.features"></Feature>
</Halo>
</div>
</div>
</template>
<script>
import Halo from '@/components/ProductHalo.vue'
import Feature from '@/components/ProductFeature.vue'
import json from '@/json/data.json'
export default {
name: 'ProductSingle',
components: {
Halo,
Feature
},
data() {
return {
products: json
}
},
computed: {
productId() {
return this.$route.params.id
}
},
methods: {
getProduct(id) {
let data = this.products
return data.filter(item => item.productId == id)
}
}
}
</script>
选项2:为一种产品创建新组件
另一种方法是保留子组件不变,但是创建代表列表中一个产品的新组件:
<template>
<div>
{{ product }}
<Halo
:featuresCount="
`circle-container-` + product.features.length.toString()
"
>
<Feature
v-for="(feature, key, index) in product.features"
:key="index"
:feature="feature"
@changeProductData="setFeatureText"
></Feature>
</Halo>
<h1>{{ clickedFeature}}</h1>
</div>
</div>
</template>
<script>
import Feature from '@/components/ProductFeature.vue'
import Halo from '@/components/ProductHalo.vue'
export default {
name: 'product',
components: {
Feature,
Halo
},
data () {
return {
clickedFeature: null
}
},
props: {
product: Object
},
methods: {
setFeatureText(e) {
this.clickedFeature = e.item.text
}
}
}
</script>
然后使用新的Product
组件:
<template>
<div>
<product
v-for="product in getProduct(productId)"
:key="product.productId"
:product="product"
></product>
</div>
</template>
<script>
import Product from '@/components/Product.vue'
import json from '@/json/data.json'
export default {
name: 'ProductSingle',
components: {
Product
},
data() {
return {
products: json
}
},
computed: {
productId() {
return this.$route.params.id
}
},
methods: {
getProduct(id) {
let data = this.products
return data.filter(item => item.productId == id)
}
}
}
</script>