如何在Vue.js中为每个组件更改类的属性?

huangapple go评论73阅读模式
英文:

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&#39;ve added to my website a reusable component &quot;LightBox&quot; 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 &quot;thumbnail&quot; for several elements. But I don&#39;t how to do it. I&#39;ve tried using v-bind, but it didn&#39;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">

                    &lt;g id=&quot;SVGRepo_bgCarrier&quot; stroke-width=&quot;0&quot; /&gt;
&lt;g id=&quot;SVGRepo_tracerCarrier&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; /&gt;
&lt;g id=&quot;SVGRepo_iconCarrier&quot;&gt;
&lt;g&gt;
&lt;g&gt;
&lt;path
d=&quot;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&quot; /&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/svg&gt;
&lt;/div&gt;
&lt;div class=&quot;lightbox-image&quot; @click.stop=&quot;&quot;&gt;
&lt;img :src=&quot;images[index]&quot; loading=&quot;lazy&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;cursor right&quot; @click.stop=&quot;next&quot; :class=&quot;{ &#39;invisible&#39;: !hasNext() }&quot;&gt;
&lt;svg class=&quot;size&quot; fill=&quot;#ffff&quot; version=&quot;1.1&quot; id=&quot;Capa_1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;
xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; width=&quot;100px&quot; height=&quot;100px&quot;
viewBox=&quot;0 0 537.66 537.66&quot; xml:space=&quot;preserve&quot; transform=&quot;rotate(180)&quot; stroke=&quot;#ffff&quot;&gt;
&lt;g id=&quot;SVGRepo_bgCarrier&quot; stroke-width=&quot;0&quot; /&gt;
&lt;g id=&quot;SVGRepo_tracerCarrier&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; /&gt;
&lt;g id=&quot;SVGRepo_iconCarrier&quot;&gt;
&lt;g&gt;
&lt;g&gt;
&lt;path
d=&quot;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&quot; /&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/svg&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

</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 =&gt; element === thumbnail);
},
show() {
this.visible = true;
this.index=this.thumbnailIndex
},
hide() {
this.visible = false;
this.index = 0;
},
hasNext() {
return this.index + 1 &lt; this.images.length;
},
hasPrev() {
return this.index - 1 &gt;= 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&#39;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: [&#39;https://picsum.photos/500&#39;, &#39;https://picsum.photos/501&#39;, &#39;https://picsum.photos/499&#39;, &#39;https://picsum.photos/502&#39;, &#39;https://picsum.photos/500&#39;, &#39;https://picsum.photos/501&#39;, &#39;https://picsum.photos/499&#39;, &#39;https://picsum.photos/502&#39;],
};
},
});
app.component(&quot;lightBox&quot;, {
template: `
&lt;div&gt;
&lt;a href=&quot;&quot; @click.prevent=&quot;show&quot;&gt;
&lt;img :style=&quot;styles&quot; :src=&quot;images[thumbnailIndex]&quot; loading=&quot;lazy&quot;&gt;
&lt;/a&gt;
&lt;div class=&quot;lightbox&quot; v-if=&quot;visible&quot; @click=&quot;hide&quot;&gt;
&lt;div class=&quot;flex&quot;&gt;
&lt;div class=&quot;cursor left&quot; @click.stop=&quot;prev&quot; :class=&quot;{ &#39;invisible&#39;: !hasPrev() }&quot;&gt;
&lt;svg fill=&quot;#ffff&quot; version=&quot;1.1&quot; id=&quot;Capa_1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; width=&quot;100px&quot; height=&quot;100px&quot; viewBox=&quot;0 0 537.66 537.66&quot; xml:space=&quot;preserve&quot;  stroke=&quot;#ffff&quot;&gt;
&lt;g id=&quot;SVGRepo_bgCarrier&quot; stroke-width=&quot;0&quot; /&gt;
&lt;g id=&quot;SVGRepo_tracerCarrier&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; /&gt;
&lt;g id=&quot;SVGRepo_iconCarrier&quot;&gt;
&lt;g&gt;
&lt;g&gt;
&lt;path d=&quot;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&quot; /&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/svg&gt;
&lt;/div&gt;
&lt;div class=&quot;lightbox-image&quot; @click.stop=&quot;&quot;&gt;
&lt;img :src=&quot;images[index]&quot; loading=&quot;lazy&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;cursor right&quot; @click.stop=&quot;next&quot; :class=&quot;{ &#39;invisible&#39;: !hasNext() }&quot;&gt;
&lt;svg class=&quot;size&quot; fill=&quot;#ffff&quot; version=&quot;1.1&quot; id=&quot;Capa_1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; width=&quot;100px&quot; height=&quot;100px&quot; viewBox=&quot;0 0 537.66 537.66&quot; xml:space=&quot;preserve&quot; transform=&quot;rotate(180)&quot; stroke=&quot;#ffff&quot;&gt;
&lt;g id=&quot;SVGRepo_bgCarrier&quot; stroke-width=&quot;0&quot; /&gt;
&lt;g id=&quot;SVGRepo_tracerCarrier&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; /&gt;
&lt;g id=&quot;SVGRepo_iconCarrier&quot;&gt;
&lt;g&gt;
&lt;g&gt;
&lt;path d=&quot;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&quot; /&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/svg&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;`,
props: {
thumbnailIndex: {
type: Array,
required: true,
},
images: {
type: Array,
default: () =&gt; [],
},
styles: {
type: String,
deafult: &#39;29vh&#39;
}
},
data() {
return {
visible: false,
index: 1,
};
},
methods: {
Index() {
let thumbnailIndex = images.findIndex(
(element) =&gt; element === thumbnail
);
},
show() {
this.visible = true;
this.index = this.thumbnailIndex;
},
hide() {
this.visible = false;
this.index = 0;
},
hasNext() {
return this.index + 1 &lt; this.images.length;
},
hasPrev() {
return this.index - 1 &gt;= 0;
},
prev() {
if (this.hasPrev()) {
this.index -= 1;
}
},
next() {
if (this.hasNext()) {
this.index += 1;
}
},
},
});
app.mount(&quot;#demo&quot;);

<!-- 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 -->

&lt;script src=&quot;https://unpkg.com/vue@3/dist/vue.global.prod.js&quot;&gt;&lt;/script&gt;
&lt;div id=&quot;demo&quot; style=&quot;display: flex; flex-wrap: wrap&quot;&gt;
&lt;light-box :thumbnail-index=&quot;0&quot; :images=&quot;images&quot; :styles=&quot;{width: &#39;25vh&#39;}&quot;&gt;&lt;/light-box&gt;
&lt;light-box :thumbnail-index=&quot;1&quot; :images=&quot;images&quot; :styles=&quot;{width: &#39;30vh&#39;}&quot;&gt;&lt;/light-box&gt;
&lt;light-box :thumbnail-index=&quot;2&quot; :images=&quot;images&quot; :styles=&quot;{width: &#39;45vh&#39;}&quot;&gt;&lt;/light-box&gt;
&lt;light-box :thumbnail-index=&quot;3&quot; :images=&quot;images&quot; :styles=&quot;{width: &#39;25vh&#39;}&quot;&gt;&lt;/light-box&gt;
&lt;/div&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年2月26日 19:05:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/75571539.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定