Open ithack opened 6 years ago
vue,@click="event()"
,添加()与不添加()的区别应该是 Vue 对函数调用表达式额外用了一个函数做了层包装。加与不加括号的区别在于事件对象参数 event 的处理。不加括号时,函数第一个参数默认为 event;加了括号后,需要手动传入 $event 才能获得事件对象。
<template>
<div class="btn-item">
<button class="btn btn-success" @click="sure($event)">确定</button>
<button class="btn btn-default" @click="quit">取消</button>
</div>
</template>
<script>
export default{
name:'test',
data(){
return {
}
},
methods:{
sure(e){
console.log(e.target);
},
quit(e){
console.log(e.target);
}
}
}
</script>
loadmore 组件修复一些bug,单独抽离出来,自定义修改,待完善
<template>
<div class="mint-loadmore">
<div class="mint-loadmore-content" :class="{ 'is-dropped': topDropped || bottomDropped}" :style="{ 'transform': 'translate3d(0, ' + translate + 'px, 0)' }">
<slot name="top">
<div class="mint-loadmore-top" v-if="topMethod">
<!--<spinner v-if="topStatus === 'loading'" class="mint-loadmore-spinner" :size="20" type="fading-circle"></spinner>-->
<span class="mint-loadmore-text">{{ topText }}</span>
</div>
</slot>
<slot></slot>
<slot name="bottom">
<div class="mint-loadmore-bottom" v-if="bottomMethod">
<!--<spinner v-if="bottomStatus === 'loading'" class="mint-loadmore-spinner" :size="20" type="fading-circle"></spinner>-->
<span class="mint-loadmore-text">{{ bottomText }}</span>
</div>
</slot>
</div>
</div>
</template>
<script>
//修复loadmore失效问题
export default {
name: 'loadmore',
props: {
maxDistance: {
type: Number,
default: 0
},
autoFill: {
type: Boolean,
default: true
},
distanceIndex: {
type: Number,
default: 2
},
topPullText: {
type: String,
default: '下拉刷新'
},
topDropText: {
type: String,
default: '释放更新'
},
topLoadingText: {
type: String,
default: '加载中...'
},
topDistance: {
type: Number,
default: 70
},
topMethod: {
type: Function
},
bottomPullText: {
type: String,
default: '上拉刷新'
},
bottomDropText: {
type: String,
default: '释放更新'
},
bottomLoadingText: {
type: String,
default: '加载中...'
},
bottomDistance: {
type: Number,
default: 70
},
bottomMethod: {
type: Function
},
bottomAllLoaded: {
type: Boolean,
default: false
}
},
data() {
return {
uuid: null,
translate: 0,
scrollEventTarget: null,
containerFilled: false,
topText: '',
topDropped: false,
bottomText: '',
bottomDropped: false,
bottomReached: false,
direction: '',
startY: 0,
startScrollTop: 0,
currentY: 0,
topStatus: '',
bottomStatus: ''
};
},
watch: {
topStatus(val) {
this.$emit('top-status-change', val);
switch (val) {
case 'pull':
this.topText = this.topPullText;
break;
case 'drop':
this.topText = this.topDropText;
break;
case 'loading':
this.topText = this.topLoadingText;
break;
}
},
bottomStatus(val) {
this.$emit('bottom-status-change', val);
switch (val) {
case 'pull':
this.bottomText = this.bottomPullText;
break;
case 'drop':
this.bottomText = this.bottomDropText;
break;
case 'loading':
this.bottomText = this.bottomLoadingText;
break;
}
}
},
methods: {
onTopLoaded(id) {
if (id === this.uuid) {
this.translate = 0;
setTimeout(() => {
this.topStatus = 'pull';
}, 200);
}
},
onBottomLoaded(id) {
this.bottomStatus = 'pull';
this.bottomDropped = false;
if (id === this.uuid) {
this.$nextTick(() => {
if (this.scrollEventTarget === window) {
document.body.scrollTop += 50;
} else {
this.scrollEventTarget.scrollTop += 50;
}
this.translate = 0;
});
}
if (!this.bottomAllLoaded && !this.containerFilled) {
this.translate='0';//修复数据加载完成后底部高度值控制
this.fillContainer();
}
},
getScrollEventTarget(element) {
let currentNode = element;
while (currentNode && currentNode.tagName !== 'HTML' &&
currentNode.tagName !== 'BODY' && currentNode.nodeType === 1) {
let overflowY = document.defaultView.getComputedStyle(currentNode).overflowY;
if (overflowY === 'scroll' || overflowY === 'auto') {
return currentNode;
}
currentNode = currentNode.parentNode;
}
return window;
},
getScrollTop(element) {
if (element === window) {
return Math.max(window.pageYOffset || 0, document.documentElement.scrollTop);
} else {
return element.scrollTop;
}
},
bindTouchEvents() {
this.$el.addEventListener('touchstart', this.handleTouchStart);
this.$el.addEventListener('touchmove', this.handleTouchMove);
this.$el.addEventListener('touchend', this.handleTouchEnd);
},
init() {
this.topStatus = 'pull';
this.bottomStatus = 'pull';
this.topText = this.topPullText;
this.scrollEventTarget = this.getScrollEventTarget(this.$el);
if (typeof this.bottomMethod === 'function') {
this.fillContainer();
this.bindTouchEvents();
}
if (typeof this.topMethod === 'function') {
this.bindTouchEvents();
}
},
fillContainer() {
if (this.autoFill) {
this.$nextTick(() => {
if (this.scrollEventTarget === window) {
this.containerFilled = this.$el.getBoundingClientRect().bottom >=
document.documentElement.getBoundingClientRect().bottom;
} else {
this.containerFilled = this.$el.getBoundingClientRect().bottom >=
this.scrollEventTarget.getBoundingClientRect().bottom;
}
if (!this.containerFilled) {
this.bottomStatus = 'loading';
this.bottomMethod(this.uuid);
}
});
}
},
checkBottomReached() {
//加载第一屏后不够一屏数据又一次加载机会
if(this.$el.getBoundingClientRect().height<document.documentElement.clientHeight){
return true;
}
if (this.scrollEventTarget === window) {
return document.documentElement.scrollTop || document.body.scrollTop + document.documentElement.clientHeight === document.body.scrollHeight;//修改源码加入document.documentElement.scrollTop 兼容
} else {
return this.$el.getBoundingClientRect().bottom <= this.scrollEventTarget.getBoundingClientRect().bottom;
}
},
handleTouchStart(event) {
this.startY = event.touches[0].clientY;
this.startScrollTop = this.getScrollTop(this.scrollEventTarget);
this.bottomReached = false;
if (this.topStatus !== 'loading') {
this.topStatus = 'pull';
this.topDropped = false;
}
if (this.bottomStatus !== 'loading') {
this.bottomStatus = 'pull';
this.bottomDropped = false;
}
},
handleTouchMove(event) {
if (this.startY < this.$el.getBoundingClientRect().top && this.startY > this.$el.getBoundingClientRect().bottom) {
return;
}
this.currentY = event.touches[0].clientY;
let distance = (this.currentY - this.startY) / this.distanceIndex;
this.direction = distance > 0 ? 'down' : 'up';
if (typeof this.topMethod === 'function' && this.direction === 'down' &&
this.getScrollTop(this.scrollEventTarget) === 0 && this.topStatus !== 'loading') {
event.preventDefault();
event.stopPropagation();
if (this.maxDistance > 0) {
this.translate = distance <= this.maxDistance ? distance - this.startScrollTop : this.translate;
} else {
this.translate = distance - this.startScrollTop;
}
if (this.translate < 0) {
this.translate = 0;
}
this.topStatus = this.translate >= this.topDistance ? 'drop' : 'pull';
}
if (this.direction === 'up') {
this.bottomReached = this.bottomReached || this.checkBottomReached();
}
if (typeof this.bottomMethod === 'function' && this.direction === 'up' &&
this.bottomReached && this.bottomStatus !== 'loading' && !this.bottomAllLoaded) {
event.preventDefault();
event.stopPropagation();
if (this.maxDistance > 0) {
this.translate = Math.abs(distance) <= this.maxDistance
? this.getScrollTop(this.scrollEventTarget) - this.startScrollTop + distance : this.translate;
} else {
this.translate = this.getScrollTop(this.scrollEventTarget) - this.startScrollTop + distance;
}
if (this.translate > 0) {
this.translate = 0;
}
this.bottomStatus = -this.translate >= this.bottomDistance ? 'drop' : 'pull';
}
},
handleTouchEnd() {
if (this.direction === 'down' && this.getScrollTop(this.scrollEventTarget) === 0 && this.translate > 0) {
this.topDropped = true;
if (this.topStatus === 'drop') {
this.translate = '50';
this.topStatus = 'loading';
this.topMethod(this.uuid);
} else {
this.translate = '0';
this.topStatus = 'pull';
}
}
if (this.direction === 'up' && this.bottomReached && this.translate < 0) {
this.bottomDropped = true;
this.bottomReached = false;
if (this.bottomStatus === 'drop') {
this.translate = '-2';//拖拽未加载情况减少可失去确实问题
this.bottomStatus = 'loading';
this.bottomMethod(this.uuid);
} else {
this.translate = '0';
this.bottomStatus = 'pull';
}
}
this.direction = '';
}
},
mounted() {
this.uuid = Math.random().toString(36).substring(3, 8);
this.init();
}
};
</script>
非父子组件传递数据;通过使用一个空的Vue实例作为中央事件总线。main.js
相邻组件1,通过$emit()传递数据
this.bus.$emit("toChangeTitle","首页");
相邻组件2,通过$on()接收数据