在backgroundImage的vue中添加过渡效果

时间:2020-04-21 21:45:17

标签: css vue.js background-image

我一直在寻找几天,以便在通过Vue应用程序更改的backgroundImage上添加淡入淡出过渡效果。

这是我一直在测试的代码段:

new Vue({
  el: "#main",
  data: {
    images: [
      "https://images.freeimages.com/images/large-previews/bfd/clouds-1371838.jpg",
      "https://images.freeimages.com/images/large-previews/ffa/water-lilly-1368676.jpg",
      "https://images.freeimages.com/images/large-previews/efb/lotus-flower-1382251.jpg"
    ],
    current: 0,
    show: false
  },
  methods: {
    changeBG: function () {
      if (this.current < this.images.length - 1) {
        this.current = this.current + 1;
      } else {
        this.current = 0;
      }
    }
  }
});
.main {
  height: 800px;
  width: 100%;
  margin-left: auto;
  margin-right: auto;
  z-index: 0;
  background-repeat: no-repeat;
  background-size: cover;	
  background-position: center 0px; 
} 
button {
  width: 200px;
  height: 25px;
  margin: 10px; 
}
p.hello{
  color: white;
  margin: 10px;
  font-size: 50px;
}

.fade-enter-active,
.fade-leave-active {
  transition: all 2s linear;
}

.fade-enter-to,
.fade-leave {
  opacity: 0;
}

.fade-enter,
.fade-leave-to {
  opacity: 1;
}

/* hello example transition */
.slide-fade-enter-active {
  transition: all 1s ease;
}
.slide-fade-leave-active {
  transition: all 1s cubic-bezier(1, 0.5, 0.8, 1);
}
.slide-fade-enter,
.slide-fade-leave-to {
  transform: translateX(10px);
  opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<transition name="fade">
  <div v-if="changeBG" class="main" id="main" :style="{ backgroundImage: 'url(\'' + images[current] + '\')' }">
    <button v-on:click="changeBG">
      changeBG
    </button>
    <div id="testFromGuide">
      <button @click="show = !show">
        toggleHello
      </button>
      <transition name="slide-fade">
        <p class="hello" v-if="show">all your base are belong to us</p>
      </transition>
    </div>
  </div>
</transition>

我的第一个问题是否完全可能?我使用backgroundImage的原因是因为我在其上使用的网站具有最易于通过此方式进行响应处理的背景(始终覆盖,不重复并保持其居中)。我的第二个问题是,如果没有,是否有可能使其在here中所述的背景下工作?

在codepen中,我添加了vue guide的示例以确保其有效,并且没有其他错误。这个例子非常完美。似乎无法找到我的示例的答案,但我开始怀疑这根本不可能,或者我似乎找不到为什么Vue未能检测到某些变化的原因。

2 个答案:

答案 0 :(得分:2)

要使Vue转换正常工作,您需要更改DOM元素。因此,如果您要更改实际图像,此方法将起作用。在您的示例中,您仅更改属性值。由于DOM具有相同的元素,因此它不会触发过渡。

但是,您可以使用:key属性说服VUE替换元素,从而为您提供2个元素之间的过渡。

您也可以像示例中一样使用嵌入式CSS设置图像。您仍然必须在CSS中创建过渡。

这是使用Vue Transition的示例

new Vue({
  el: "#main",
  data: {
		currentID: 0,
    images: [
'https://images.freeimages.com/images/large-previews/efb/lotus-flower-1382251.jpg',
'https://images.freeimages.com/images/large-previews/ffa/water-lilly-1368676.jpg',
'https://images.freeimages.com/images/large-previews/bfd/clouds-1371838.jpg'
		]
  },
  methods: {
    toggleImage: function(){
       if(this.currentID < this.images.length-1){
				 this.currentID +=1
			 } else {
				 this.currentID = 0
			 } 	   
    }
  }
});
body {
  overflow: hidden;
}

.main {
  position: relative;
}

img {
  width: 100%;
  height: auto;
  display: block;
  position: absolute;
  -webkit-transition: all 3s ease;
  transition: all 3s ease;
}

button {
  z-index: 100;
  position: relative;
  width: 200px;
  height: 25px;
  margin: 20px;
}

/* prefix with transition name */
.slide-fade-enter-active {
  opacity: 1;
  z-index: 10;
}

.slide-fade-leave-active {
  opacity: 1;
}

.slide-fade-enter,
.slide-fade-leave-to {
  opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<div class="main" id="main">
    <transition name="slide-fade">
<!-- 			SRC comes from the array of images the :key is important for vue to believe its a 'new' DOM element and do the transition -->
      <img v-bind:src="images[currentID]" v-bind:key="currentID" />
    </transition>
	<button @click="toggleImage">
      Toggle Image
    </button>
</div>

但是,由于它使用图像标签,因此您对此没有太多控制权。相反,最好使用这样的背景图片:

new Vue({
  el: "#main",
  data: {
		currentID: 0,
    images: [
'https://images.freeimages.com/images/large-previews/efb/lotus-flower-1382251.jpg',
'https://images.freeimages.com/images/large-previews/ffa/water-lilly-1368676.jpg',
'https://images.freeimages.com/images/large-previews/bfd/clouds-1371838.jpg'
		]
  },
  methods: {
    toggleImage: function(){
       if(this.currentID < this.images.length-1){
				 this.currentID +=1
			 } else {
				 this.currentID = 0
			 } 	   
    }
  }
});
.main {
  /* make this the size of the window */
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

.theImage {
  width: 100%;
  height: 100%;
  position: absolute;
  background-color: #333;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center center;
  -webkit-transition: all 3s ease;
  transition: all 3s ease;
}

button {
  z-index: 100;
  position: relative;
  width: 200px;
  height: 25px;
  margin: 20px;
}

/* prefix with transition name */
.slide-fade-enter-active {
  opacity: 1;
  z-index: 10;
}

.slide-fade-leave-active {
  opacity: 1;
}

.slide-fade-enter,
.slide-fade-leave-to {
  opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<div class="main" id="main">
    <transition name="slide-fade">
<!-- 			SRC comes from the array of images the :key is important for vue to believe its a 'new' DOM element and do the transition -->
			<div class="theImage" v-bind:style="{'background-image': 'url(' + images[currentID] + ')'}" v-bind:key="currentID"></div>
    </transition>
	<button @click="toggleImage">
      Toggle Image
    </button>
</div>

答案 1 :(得分:0)

答案确实是忘记了vue转换,而让CSS做这些工作。一个有效的示例可以在这里找到:

new Vue({
  el: "#main",
  data: {
    show: false,
    BG1: true,
    BG2: false,
    BG3: false
  },
  methods: {
    changeBG: function(){
    	if (this.BG1 == true){
				this.BG1 = false;
				this.BG2 = true;
        this.BG3 = false;
			} else if (this.BG2 == true) {
				this.BG1 = false;
				this.BG2 = false;
        this.BG3 = true;
			} else if (this.BG3 == true) {
				this.BG1 = true;
				this.BG2 = false;
        this.BG3 = false;
			}       
    },
    showBG1: function(){
			if (this.BG1 == true){
				return "";
			} else {
				return "transparent";
			}
    },
    showBG2: function(){
			if (this.BG2 == true){
				return "";
			} else {
				return "transparent";
			}
    },
    showBG3: function(){
			if (this.BG3 == true){
				return "";
			} else {
				return "transparent";
			}
    }    
  }
});
.main {
} 

#bgs img.transparent {
  opacity:0;
  transform: translateY(-0.0px);
}

#bgs img{
  /* Set rules to fill background */
  min-height: 100%;
  min-width: 1024px;
	
  /* Set up proportionate scaling */
  width: 100%;
  height: auto;
	
  /* Set up positioning */
  position: fixed;
  top: 0;
  left: 0;
  
  z-index: -1;
  -webkit-transition: all 0.5s ease-in-out;
  -moz-transition: all 0.5s ease-in-out;
  -o-transition: all 0.5s ease-in-out;
  transition: all 0.5s ease-in-out;    
}

@media screen and (max-width: 1024px) { /* Specific to this particular image */
  #bgs img{
    left: 50%;
    margin-left: -512px;   /* 50% */
  }
}

button {
  z-index: 100;
  position: relative;
  width: 200px;
  height: 25px;
  margin: 20px; 
}
p.hello{
  color: white;
  margin: 40px;
  font-size: 50px;
}

.fade-enter-active {
  transition: all 1s ease;
}
.fade-leave-active {
  transition: all 1s ease;
}
.fade-enter, .fade-leave-to{
  transform: translateY(-5px);
  opacity: 0;
}

/* hello example transition */
.slide-fade-enter-active {
  transition: all 1s ease;
}
.slide-fade-leave-active {
  transition: all 1s cubic-bezier(1, 0.5, 0.8, 1);
}
.slide-fade-enter,
.slide-fade-leave-to {
  transform: translateY(-5px);
  opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<div class="main" id="main">
  <div id="bgs">
    <img :class="showBG1()" src="https://images.freeimages.com/images/large-previews/efb/lotus-flower-1382251.jpg">
    <img :class="showBG2()" src="https://images.freeimages.com/images/large-previews/ffa/water-lilly-1368676.jpg">
   <img :class="showBG3()" src="https://images.freeimages.com/images/large-previews/bfd/clouds-1371838.jpg">
  </div>
  <button @click="changeBG">
    changeBG
  </button>
  <div id="testFromGuide">
    <button @click="show = !show">
      toggleHello
    </button>
    <transition name="slide-fade">
      <p class="hello" v-if="show">all your base are belong to us</p>
    </transition>
  </div>
</div>

这还不是很完美,因为对于每个额外的背景,我都需要添加一个函数并向changeBG函数添加一个额外的 if else 循环。如果可以使用列表变量来完成此操作,则将更为优雅,但我还没有找到一种使用:class方法进行此操作的方法。我希望稍后再进行调查。