英文:
How to change classes' property for each component in Vue.js?
问题
以下是您的代码的中文翻译部分:
我已经在我的网站上添加了一个可重复使用的组件 "LightBox",它提供了具有更大分辨率的图片。这个 LightBox 是基于每个元素都有缩略图的事实构建的。我的问题是什么?我有几个元素,我想为其中的几个元素更改 "thumbnail" 类的属性。但我不知道如何做到这一点。我尝试过使用 v-bind,但对我来说没有用。
我的代码:
<template>
<div>
<a href="" @click.prevent="show">
<img class="thumbnail" :src="images[thumbnailIndex]" loading="lazy">
</a>
<div class="lightbox" v-if="visible" @click="hide">
<div class="flex">
<div class="cursor left" @click.stop="prev" :class="{ 'invisible': !hasPrev() }">
<svg fill="#ffff" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px"
viewBox="0 0 537.66 537.66" xml:space="preserve" stroke="#ffff">
<g id="SVGRepo_bgCarrier" stroke-width="0" />
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round" />
<g id="SVGRepo_iconCarrier">
<g>
<g>
<path
d="M526.375,175.442H249.458l101.781-115.23c2.939-5.875-0.006-10.64-6.574-10.64H194.735 c-15.012,0.003-34.74,30.233-44.538,41.188C132.96,110.028,3.146,254.326,2.204,256.208c-2.938,5.875-2.938,15.404,0,21.279 L177.52,477.449c2.938,5.875,10.646,10.64,17.215,10.64h149.931c6.57,0,9.514-4.765,6.576-10.64l-98.746-114.347h273.879 c6.234,0,11.285-5.052,11.285-11.285v-165.09C537.66,180.494,532.609,175.442,526.375,175.442z" />
</g>
</g>
</g>
</svg>
</div>
<div class="lightbox-image" @click.stop="">
<img :src="images[index]" loading="lazy">
</div>
<div class="cursor right" @click.stop="next" :class="{ 'invisible': !hasNext() }">
<svg class="size" fill="#ffff" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px"
viewBox="0 0 537.66 537.66" xml:space="preserve" transform="rotate(180)" stroke="#ffff">
<g id="SVGRepo_bgCarrier" stroke-width="0" />
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round" />
<g id="SVGRepo_iconCarrier">
<g>
<g>
<path
d="M526.375,175.442H249.458l101.781-115.23c2.939-5.875-0.006-10.64-6.574-10.64H194.735 c-15.012,0.003-34.74,30.233-44.538,41.188C132.96,110.028,3.146,254.326,2.204,256.208c-2.938,5.875-2.938,15.404,0,21.279 L177.52,477.449c2.938,5.875,10.646,10.64,17.215,10.64h149.931c6.57,0,9.514-4.765,6.576-10.64l-98.746-114.347h273.879 c6.234,0,11.285-5.052,11.285-11.285v-165.09C537.66,180.494,532.609,175.442,526.375,175.442z" />
</g>
</g>
</g>
</svg>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
thumbnailIndex: {
type: Array,
required: true,
},
images: {
type: Array,
default: () => [],
},
},
data
<details>
<summary>英文:</summary>
I've added to my website a reusable component "LightBox" that provides a picture with bigger resolution. This LightBox is based on the fact that each element has thumbnail. What is my issue? I have several elements where I want to change properties of class "thumbnail" for several elements. But I don't how to do it. I've tried using v-bind, but it didn't work for me
My code:
<template>
<div>
<a href="" @click.prevent="show">
<img class="thumbnail" :src="images[thumbnailIndex]" loading="lazy">
</a>
<div class="lightbox" v-if="visible" @click="hide">
<div class="flex">
<div class="cursor left" @click.stop="prev" :class="{ 'invisible': !hasPrev() }">
<svg fill="#ffff" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px"
viewBox="0 0 537.66 537.66" xml:space="preserve" stroke="#ffff">
<g id="SVGRepo_bgCarrier" stroke-width="0" />
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round" />
<g id="SVGRepo_iconCarrier">
<g>
<g>
<path
d="M526.375,175.442H249.458l101.781-115.23c2.939-5.875-0.006-10.64-6.574-10.64H194.735 c-15.012,0.003-34.74,30.233-44.538,41.188C132.96,110.028,3.146,254.326,2.204,256.208c-2.938,5.875-2.938,15.404,0,21.279 L177.52,477.449c2.938,5.875,10.646,10.64,17.215,10.64h149.931c6.57,0,9.514-4.765,6.576-10.64l-98.746-114.347h273.879 c6.234,0,11.285-5.052,11.285-11.285v-165.09C537.66,180.494,532.609,175.442,526.375,175.442z" />
</g>
</g>
</g>
</svg>
</div>
<div class="lightbox-image" @click.stop="">
<img :src="images[index]" loading="lazy">
</div>
<div class="cursor right" @click.stop="next" :class="{ 'invisible': !hasNext() }">
<svg class="size" fill="#ffff" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px"
viewBox="0 0 537.66 537.66" xml:space="preserve" transform="rotate(180)" stroke="#ffff">
<g id="SVGRepo_bgCarrier" stroke-width="0" />
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round" />
<g id="SVGRepo_iconCarrier">
<g>
<g>
<path
d="M526.375,175.442H249.458l101.781-115.23c2.939-5.875-0.006-10.64-6.574-10.64H194.735 c-15.012,0.003-34.74,30.233-44.538,41.188C132.96,110.028,3.146,254.326,2.204,256.208c-2.938,5.875-2.938,15.404,0,21.279 L177.52,477.449c2.938,5.875,10.646,10.64,17.215,10.64h149.931c6.57,0,9.514-4.765,6.576-10.64l-98.746-114.347h273.879 c6.234,0,11.285-5.052,11.285-11.285v-165.09C537.66,180.494,532.609,175.442,526.375,175.442z" />
</g>
</g>
</g>
</svg>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
thumbnailIndex: {
type: Array,
required: true,
},
images: {
type: Array,
default: () => [],
},
},
data() {
return {
visible: false,
index: 1,
};
},
methods: {
Index(){
let thumbnailIndex = images.findIndex(element => element === thumbnail);
},
show() {
this.visible = true;
this.index=this.thumbnailIndex
},
hide() {
this.visible = false;
this.index = 0;
},
hasNext() {
return this.index + 1 < this.images.length;
},
hasPrev() {
return this.index - 1 >= 0
},
prev() {
if (this.hasPrev()) {
this.index -= 1;
}
},
next() {
if (this.hasNext()) {
this.index += 1
}
}
}
}
</script>
<style>
.thumbnail {
width: 29vh;
}
.lightbox {
position: fixed;
z-index: 500;
display: flex;
justify-content: center;
align-content: center;
background: rgba(0, 0, 0, 0.8);
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100%;
height: 100%;
}
.lightbox-image img {
width: auto;
height: auto;
max-width:50%;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.cursor {
cursor: pointer;
display: block;
position: absolute;
z-index: 1000;
top: 50%;
visibility: visible;
}
.cursor.right {
right: 10%;
}
.cursor.left {
left: 10%;
}
.invisible {
visibility: hidden;
}
@media screen and (max-width: 1024px) {
.thumbnail{
width: 100%;
}
.lightbox-image img{
max-width: 80%;
max-height: 80%;;
}
.cursor{
top: 70%;
}
}
</style>
This is how I've tried to change classes for each thubmnail
<LightBox :thumbnail-index="0" :images="images" :style="{width: "25vh"}"></LightBox>
<LightBox :thumbnail-index="1" :images="images" :style="{width: "25vh"}"></LightBox>
<LightBox :thumbnail-index="2" :images="images" :style="{width: "25vh"}"></LightBox>
<LightBox :thumbnail-index="3" :images="images" :style="{width: "25vh"}"></LightBox>
</details>
# 答案1
**得分**: 2
```javascript
如果我理解你的意思正确,请看以下代码段:
(传递你需要的样式并将其绑定)
const app = Vue.createApp({
data() {
return {
images: ['https://picsum.photos/500', 'https://picsum.photos/501', 'https://picsum.photos/499', 'https://picsum.photos/502', 'https://picsum.photos/500', 'https://picsum.photos/501', 'https://picsum.photos/499', 'https://picsum.photos/502'],
};
},
});
app.component("lightBox", {
template: `
<div>
<a href="" @click.prevent="show">
<img :style="styles" :src="images[thumbnailIndex]" loading="lazy">
</a>
<div class="lightbox" v-if="visible" @click="hide">
<div class="flex">
<div class="cursor left" @click.stop="prev" :class="{ 'invisible': !hasPrev() }">
<svg fill="#ffff" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px" viewBox="0 0 537.66 537.66" xml:space="preserve" stroke="#ffff">
...
</svg>
</div>
<div class="lightbox-image" @click.stop="">
<img :src="images[index]" loading="lazy">
</div>
<div class="cursor right" @click.stop="next" :class="{ 'invisible': !hasNext() }">
<svg class="size" fill="#ffff" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px" viewBox="0 0 537.66 537.66" xml:space="preserve" transform="rotate(180)" stroke="#ffff">
...
</svg>
</div>
</div>
</div>
</div>`,
props: {
thumbnailIndex: {
type: Array,
required: true,
},
images: {
type: Array,
default: () => [],
},
styles: {
type: String,
default: '29vh'
}
},
data() {
return {
visible: false,
index: 1,
};
},
methods: {
Index() {
let thumbnailIndex = images.findIndex(
(element) => element === thumbnail
);
},
show() {
this.visible = true;
this.index = this.thumbnailIndex;
},
hide() {
this.visible = false;
this.index = 0;
},
hasNext() {
return this.index + 1 < this.images.length;
},
hasPrev() {
return this.index - 1 >= 0;
},
prev() {
if (this.hasPrev()) {
this.index -= 1;
}
},
next() {
if (this.hasNext()) {
this.index += 1;
}
},
},
});
app.mount("#demo");
/* CSS部分 */
.lightbox {
...
}
.lightbox-image img {
...
}
.cursor {
...
}
.cursor.right {
...
}
.cursor.left {
...
}
.invisible {
...
}
@media screen and (max-width: 1024px) {
...
}
/* HTML部分 */
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo" style="display: flex; flex-wrap: wrap">
<light-box :thumbnail-index="0" :images="images" :styles="{width: '25vh'}"></light-box>
<light-box :thumbnail-index="1" :images="images" :styles="{width: '30vh'}"></light-box>
<light-box :thumbnail-index="2" :images="images" :styles="{width: '45vh'}"></light-box>
<light-box :thumbnail-index="3" :images="images" :styles="{width: '25vh'}"></light-box>
</div>
英文:
If I understood you correctly, please take a look at following snippet:
(pass styles you need and bind it)
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const app = Vue.createApp({
data() {
return {
images: ['https://picsum.photos/500', 'https://picsum.photos/501', 'https://picsum.photos/499', 'https://picsum.photos/502', 'https://picsum.photos/500', 'https://picsum.photos/501', 'https://picsum.photos/499', 'https://picsum.photos/502'],
};
},
});
app.component("lightBox", {
template: `
<div>
<a href="" @click.prevent="show">
<img :style="styles" :src="images[thumbnailIndex]" loading="lazy">
</a>
<div class="lightbox" v-if="visible" @click="hide">
<div class="flex">
<div class="cursor left" @click.stop="prev" :class="{ 'invisible': !hasPrev() }">
<svg fill="#ffff" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px" viewBox="0 0 537.66 537.66" xml:space="preserve" stroke="#ffff">
<g id="SVGRepo_bgCarrier" stroke-width="0" />
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round" />
<g id="SVGRepo_iconCarrier">
<g>
<g>
<path d="M526.375,175.442H249.458l101.781-115.23c2.939-5.875-0.006-10.64-6.574-10.64H194.735 c-15.012,0.003-34.74,30.233-44.538,41.188C132.96,110.028,3.146,254.326,2.204,256.208c-2.938,5.875-2.938,15.404,0,21.279 L177.52,477.449c2.938,5.875,10.646,10.64,17.215,10.64h149.931c6.57,0,9.514-4.765,6.576-10.64l-98.746-114.347h273.879 c6.234,0,11.285-5.052,11.285-11.285v-165.09C537.66,180.494,532.609,175.442,526.375,175.442z" />
</g>
</g>
</g>
</svg>
</div>
<div class="lightbox-image" @click.stop="">
<img :src="images[index]" loading="lazy">
</div>
<div class="cursor right" @click.stop="next" :class="{ 'invisible': !hasNext() }">
<svg class="size" fill="#ffff" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px" viewBox="0 0 537.66 537.66" xml:space="preserve" transform="rotate(180)" stroke="#ffff">
<g id="SVGRepo_bgCarrier" stroke-width="0" />
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round" />
<g id="SVGRepo_iconCarrier">
<g>
<g>
<path d="M526.375,175.442H249.458l101.781-115.23c2.939-5.875-0.006-10.64-6.574-10.64H194.735 c-15.012,0.003-34.74,30.233-44.538,41.188C132.96,110.028,3.146,254.326,2.204,256.208c-2.938,5.875-2.938,15.404,0,21.279 L177.52,477.449c2.938,5.875,10.646,10.64,17.215,10.64h149.931c6.57,0,9.514-4.765,6.576-10.64l-98.746-114.347h273.879 c6.234,0,11.285-5.052,11.285-11.285v-165.09C537.66,180.494,532.609,175.442,526.375,175.442z" />
</g>
</g>
</g>
</svg>
</div>
</div>
</div>
</div>`,
props: {
thumbnailIndex: {
type: Array,
required: true,
},
images: {
type: Array,
default: () => [],
},
styles: {
type: String,
deafult: '29vh'
}
},
data() {
return {
visible: false,
index: 1,
};
},
methods: {
Index() {
let thumbnailIndex = images.findIndex(
(element) => element === thumbnail
);
},
show() {
this.visible = true;
this.index = this.thumbnailIndex;
},
hide() {
this.visible = false;
this.index = 0;
},
hasNext() {
return this.index + 1 < this.images.length;
},
hasPrev() {
return this.index - 1 >= 0;
},
prev() {
if (this.hasPrev()) {
this.index -= 1;
}
},
next() {
if (this.hasNext()) {
this.index += 1;
}
},
},
});
app.mount("#demo");
<!-- language: lang-css -->
.lightbox {
position: fixed;
z-index: 500;
display: flex;
justify-content: center;
align-content: center;
background: rgba(0, 0, 0, 0.8);
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100%;
height: 100%;
}
.lightbox-image img {
width: auto;
height: auto;
max-width:50%;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.cursor {
cursor: pointer;
display: block;
position: absolute;
z-index: 1000;
top: 50%;
visibility: visible;
}
.cursor.right {
right: 10%;
}
.cursor.left {
left: 10%;
}
.invisible {
visibility: hidden;
}
@media screen and (max-width: 1024px) {
.lightbox-image img{
max-width: 80%;
max-height: 80%;;
}
.cursor{
top: 70%;
}
}
<!-- language: lang-html -->
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo" style="display: flex; flex-wrap: wrap">
<light-box :thumbnail-index="0" :images="images" :styles="{width: '25vh'}"></light-box>
<light-box :thumbnail-index="1" :images="images" :styles="{width: '30vh'}"></light-box>
<light-box :thumbnail-index="2" :images="images" :styles="{width: '45vh'}"></light-box>
<light-box :thumbnail-index="3" :images="images" :styles="{width: '25vh'}"></light-box>
</div>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论