从昨天开始,我一直在与这个问题作斗争,而且我机智。当前,我在vue文件中有一个方法可以做到这一点:
methods: {
showSlides(n) {
let slides = document.getElementsByClassName("mySlides");
slides[0].style.display = "block";
}
},
mounted(){
this.showSlides();
}
它找到所有具有“ mySlides”类的元素,将它们存储在变量中,然后尝试更改第一个元素的样式。组件mount()时将调用此函数。
现在,问题是我得到一个错误,指出"TypeError: Cannot read property 'style' of undefined"
。事实证明,在执行此功能时,这些DOM元素是未定义的。我通过向按钮添加@click='showSlide()'
事件来实现这一点。当我单击按钮时,该函数成功运行,但是,当安装mount()时,该函数却无法运行。
该代码还可以在纯HTML文件中成功运行,该HTML文件的脚本位于页面底部。这就是让我相信有些可疑的事情正在发生。
完整代码:
<template>
<div class="wrapper">
<div class="sight-container">
<p class='sight-name'>{{ sight.name }}</p>
<p>{{ sight.formatted_address }}</p>
<p>{{ sight.formatted_phone_number }}</p>
<p>{{ sight.international_phone_number }}</p>
<p>{{ sight.website }}</p>
<div class="photos-container">
<div v-for='(image, index) in sightImages' class="mySlides">
<div class="numbertext">{{ index + 1 }} / {{ sightImages.length }}</div>
<img class='sight-photos' :src="'https://maps.googleapis.com/maps/api/place/photo?maxwidth=1920&photoreference=' + image.photo_reference + '&key='">
</div>
<a class="prev" @click='plusSlides(-1)'>❮</a>
<a class="next" @click='plusSlides(1)'>❯</a>
<div class="caption-container">
<p id="caption"></p>
</div>
<div class="row">
<div v-for='(image, index) in sightImages' class="column">
<img class="demo cursor" :src="'https://maps.googleapis.com/maps/api/place/photo?maxwidth=1920&photoreference=' + image.photo_reference + '&key='" style="width:100%" @click="currentSlide(1)">
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
data(){
return {
placeId: this.$route.params.placeid,
sight: "",
sightImages: [],
slideIndex: 1
}
},
methods: {
showSlides(n) {
let i;
let slides = document.getElementsByClassName("mySlides");
let dots = document.getElementsByClassName("demo");
let captionText = document.getElementById("caption");
if (n > slides.length) {
this.slideIndex = 1
}
if (n < 1) {
this.slideIndex = slides.length
}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[this.slideIndex-1].style.display = "block";
dots[this.slideIndex-1].className += " active";
captionText.innerHTML = dots[this.slideIndex-1].alt;
},
plusSlides(n) {
this.showSlides(this.slideIndex += n);
},
currentSlide(n) {
this.showSlides(this.slideIndex = n);
}
},
mounted(){
axios.get('/getSight/' + this.placeId)
.then(response => {
this.sight = response.data.result.result
this.sightImages = response.data.result.result.photos
}).catch((error) => console.log(error));
this.showSlides(this.slideIndex);
}
}
</script>
答案 0 :(得分:1)
那是因为您使用错误。
通常,mounted
在渲染组件的DOM之后称为,此时组件的this.$el
就可以使用了。
但是,在mounted
中,您要调用异步操作,该操作会在完成后更新data
(及更高版本的DOM),但是您尝试使用其结果 发生了。
应该是这样的:
mounted() {
axios.get('/getSight/' + this.placeId)
.then(response => {
this.sight = response.data.result.result;
this.sightImages = response.data.result.result.photos;
this.$nextTick(() => {
this.showSlides(this.slideIndex);
});
}).catch((error) => console.log(error));
}
小提示:您可以使用el.className += ...
和el.className.replace(...)
来代替el.classList.add(...)
和el.classList.remove(...)
。