vue 组件状态冲突
vue 组件状态冲突在写vue组件Carousel 时,出现在同一个页面中多次使用同一个组件时的状态冲突,原因是过多的使用了JavaScript原生的DOM操作方式,修改使用vue中ref 操作DOM元素后,则此冲突消失;vue中对于ref的解释为:ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 D...
·
vue 组件状态冲突
在写vue组件Carousel 时,出现在同一个页面中多次使用同一个组件时的状态冲突,原因是过多的使用了JavaScript原生的DOM操作方式,修改使用vue中ref 操作DOM元素后,则此冲突消失;
vue中对于ref的解释为:ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例.
<template>
<div class="yu-carousel" ref="carousel"
:class="[type]"
:style="{width:width,height:height}">
<ul class="yu-img-warp" ref="warp">
<slot/>
<yu-carousel-item :src="lastSrc" v-if="!type"/>
</ul>
<ol v-if="!type" ref="lines"> //***添加 ref 用于操作DOM元素***
<li v-for="(value,index) in items"></li>
</ol>
<div class="carousel-arrow">
<a ref="left" href="javascript:;" class="left_arrow"><i class="iconfont icon-angle-left"></i></a>
<a ref="right" href="javascript:;" class="right_arrow"><i class="iconfont icon-angle-right"></i></a>
</div>
</div>
</template>
<script>
import YuCarouselItem from './carousel-item';
export default {
name: 'YuCarousel',
components: {
YuCarouselItem,
},
props: {
width: String,
height: String,
autoplay: false,
interval: Number,
type: String,
position: null,
},
data() {
return {
items: 0,
lastSrc: String,
}
},
methods: {
},
mounted() {
// 动画函数
function animate(element, target, num) {
num = num || 10;
clearInterval(element.timer);
element.timer = setInterval( () => {
let leader = element.offsetLeft;
let step = target > leader ? num : -num;
if (Math.abs(target - leader) >= Math.abs(step)) {
leader += step;
element.style.left = leader + "px";
} else {
clearInterval(element.timer);
element.style.left = target + "px";
}
}, 15);
}
function animate1(element, obj, fn){
clearInterval(element.timer);
element.timer = setInterval(() => {
let flag = true;
for(let k in obj) {
let style = k;
let target = obj[k];
if (k === 'opacity') {
let leader = getStyle(element, style);
leader = parseFloat(leader) || 0;
leader *= 1000;
target *= 1000;
let step = (target - leader)/10;
step = step>0?Math.ceil(step):Math.floor(step);
leader += step;
element.style[style] = leader / 1000;
if (leader !== target) {
flag = false;
}
} else if (k === 'zIndex') {
element.style.zIndex = target;
} else {
let leader = getStyle(element, style);
leader = parseInt(leader) || 0;
let step = (target - leader) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
leader += step;
element.style[style] = `${leader}px`;
if (leader !== target) {
flag = false;
}
}
}
if (flag) {
clearInterval(element.timer);
fn && fn();
}
}, 15);
}
function getStyle(element, style) {
if ('getComputedStyle' in window) {
return window.getComputedStyle(element, null)[style];
} else {
return element.currentStyle[style];
}
}
let lines = null;
const carousel = this.$refs.carousel;
const ul = carousel.children[0];
const leftArrow = this.$refs.left;
const rightArrow = this.$refs.right;
const imgs = ul.children;
const imgWidth = carousel.offsetWidth;
let lock = true;
const arr = this.position;
let count = 0;
let timer = null;
if (!this.type) {
this.$nextTick(() => {
lines = this.$refs.lines.children;
lines[0].className = 'now';
console.log(lines);
// 小圆点
for (let i = 0; i < lines.length; i++) {
lines[i].index = i;
lines[i].addEventListener('click', () => {
for (let j = 0; j < lines.length; j++) {
lines[j].className = '';
}
lines[this.index].className = 'now';
animate(ul, -this.index * imgWidth, 50);
})
}
});
}
this.lastSrc = this.$children[0].src;
this.items = this.$children.length - 1;
this.$refs.warp.style.width = `${this.$children.length}00%`;
// const list = document.querySelectorAll('.yu-img-warp li'); **有冲突时的代码**
const list = this.$refs.warp.children; // **修改之后 无冲突,使用啦 ref操作DOM元素**
for (let i = 0; i < list.length; i++) {
list[i].style.width = `${(1 / this.$children.length) * 100}%`;
}
// 轮播图
if (this.type) {
for (let i = 0; i < imgs.length; i++) {
animate1(imgs[i], arr[i]);
}
}
rightArrow.addEventListener('click', () => {
// 普通轮播图
if (this.type) {
if (lock) {
lock = false;
arr.unshift(arr.pop());
for (let i = 0; i < imgs.length; i ++) {
animate1(imgs[i], arr[i], () => {
lock = true;
})
}
}
} else {
if (count >= imgs.length - 1) {
ul.style.left = 0;
count = 0
}
count += 1;
animate(ul, -count * imgWidth, 50);
for (let i = 0; i < lines.length; i++) {
lines[i].className = '';
}
if (count >= imgs.length - 1) {
lines[0].className = 'now';
} else {
lines[count].className = 'now';
}
}
});
// 左箭头
leftArrow.addEventListener('click', () => {
if (this.type) {
if (lock) {
lock = false;
arr.push(arr.shift());
for (let i = 0; i < imgs.length; i++) {
animate1(imgs[i], arr[i], () => {
lock = true;
})
}
}
} else {
// 普通轮播图
if (count <= 0) {
count = imgs.length - 1;
ul.style.left = `${-count * imgWidth}px`;
}
count -= 1;
animate(ul, -count * imgWidth, 50);
for (let i = 0; i < lines.length; i++) {
lines[i].className = '';
}
lines[count].className = 'now';
}
});
// line
// 自动播放
let that = this;
function auto() {
timer = setInterval(() => {
rightArrow.click();
}, that.interval);
}
if (this.autoplay) {
auto();
carousel.onmouseover = () => {
clearInterval(timer);
};
carousel.onmouseout = () => {
clearInterval(timer);
auto();
}
}
},
}
</script>
更多推荐
已为社区贡献2条内容
所有评论(0)