Git Product home page Git Product logo

vue-scroller's Introduction

Vue Scroller version vue

Vue Scroller is a foundational component of Vonic UI. In purpose of smooth scrolling, pull to refresh and infinite loading.

For vue 1.0, please refer to branch v1.

Demo

https://wangdahoo.github.io/vue-scroller/

How to use

npm i vue-scroller -S
/* ignore this if you include vue-scroller.js by <script> tag from a cdn, such as unpkg */
import Vue from 'vue'
import VueScroller from 'vue-scroller'
Vue.use(VueScroller)
<scroller 
  :on-refresh="refresh"
  :on-infinite="infinite">
  <!-- content goes here -->
</scroller>

Live Code on JsFiddle

Webpack project by vue-cli

https://github.com/wangdahoo/vue-scroller-demo

API

Scroller component attributes:

Attr. Name Description Required Default Value
onRefresh pull to refresh callback N -
onInfinite infinite loading callback N -
refreshText tips of pull-to-refresh N 下拉刷新
noDataText tips of no-more-data when infinite-loading finished N 没有更多数据
width scroller container width N 100%
height scroller container height N 100%
snapping enable snapping mode N false
snappingWidth snapping width N 100 (stand for 100px)
snappingHeight snapping height N 100
refreshLayerColor text color of pull-to-refresh layer N #AAA
loadingLayerColor text color of infinite-loading layer N #AAA
minContentHeight min content height (px) of scroll-content N 0

Scroller vm instance methods:

  • resize() resize scroller content (deprecated, cause the scroller's content resizes self automatically)
  • triggerPullToRefresh() start pull-to-refresh manually
  • finishPullToRefresh() stop pull-to-refresh
  • finishInfinite(isNoMoreData :Boolean) stop infinite-loading
  • scrollTo(x:Integer, y:Integer, animate:Boolean) scroll to a position in scroller content
  • scrollBy(x:Integer, y:Integer, animate:Boolean) scroll by a position in scroller content
  • getPosition :Object get current position of scroller content

vue-scroller's People

Contributors

wangdahoo avatar zhengqinyu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-scroller's Issues

没有动画效果// Cannot read property 'Animate' of undefined

core.js?e148:1319 Uncaught TypeError: Cannot read property 'Animate' of undefined
at Scroller.__publish (eval at (app.js:838), :864:37)
at Scroller.scrollTo (eval at (app.js:838), :494:10)
at Scroller.doTouchEnd (eval at (app.js:838), :791:11)
at VueComponent.touchEnd (eval at (app.js:862), :200:21)
at VueComponent.eval [as touchEnd] (eval at (app.js:657), :216:54)
at VueComponent.eval (eval at makeGetterFn (eval at (app.js:657)), :3:15)
at HTMLDivElement.handler (eval at (app.js:657), :8606:10)

Uncaught SyntaxError: Unexpected token import

按照你的step来run ,报错~
Uncaught SyntaxError: Unexpected token import at Object.<anonymous> (http://localhost:8080/app.js:1260:2) at __webpack_require__ (http://localhost:8080/app.js:556:30) at fn (http://localhost:8080/app.js:87:20) at eval (eval at <anonymous> (http://localhost:8080/app.js:876:2), <anonymous>:7:20) at Object.<anonymous> (http://localhost:8080/app.js:876:2) at __webpack_require__ (http://localhost:8080/app.js:556:30) at fn (http://localhost:8080/app.js:87:20) at eval (eval at <anonymous> (http://localhost:8080/app.js:1080:2), <anonymous>:7:19) at Object.<anonymous> (http://localhost:8080/app.js:1080:2) at __webpack_require__ (http://localhost:8080/app.js:556:30)

infinite无法触发

async mounted() {
    var Res = await this.GetData();
    for(let i = 0; i < Res.list.length; i++){
        this.Orders.push(Res.list[i]);
    }
    var vm = this;
    setTimeout(function() {
        vm.$refs.my_scroller.resize();
        vm.loaded = true;
    });
},
methods: {
    async refresh() {
        var vm = this;
        setTimeout(async () => {
            vm.Orders = [];
            var Res = await vm.GetData();
            for(let i =0;i<Res.list.length;i++){
                vm.Orders.push(Res.list[i]);
            }
            if (vm.$refs.my_scroller)
                vm.$refs.my_scroller.finishPullToRefresh();
        }, 1500)
    },
    infinite() {
        var vm = this;
        console.info(vm.loaded);
        if(vm.loaded){
            setTimeout(async function() {
                var Res = await vm.GetData();
                for(let i =0;i<Res.list.length;i++){
                    vm.Orders.push(Res.list[i]);
                }
                setTimeout(() => {
                    if (vm.$refs.my_scroller)
                    vm.$refs.my_scroller.resize();
                })
            }, 1500);
        }
    },
    async GetData(){
        try {
            var map = new Map();
            map.set('waiting_delivery','等待交付');
            map.set('success','交易完成');
            let Res = await Ajax.Get('user/order-list');   
            if(Res.list.length > 0 ){
                this.isData = true;
            }
            for(let i = 0; i < Res.list.length;i++){
                Res.list[i].status = map.get(Res.list[i].status);
                // this.Orders.push(Res.list[i]);
            }
            return Res;
        } catch (error) {
            console.info(error);
        }
    },
    RightPanel(mode) {
        this.ShowRightPanel = mode;
    },
    SearchInputFocus() {
        this.SearchBtn = !this.SearchBtn;
    },
    Search() {
        this.SearchInputFocus();
        this.GetData();
    }
}
<scroller 
    style="top:6rem;" 
    ref="my_scroller"
    :on-refresh="refresh"
    :on-infinite="infinite">
    <div class="cell" v-for="item in Orders">
        <div class="cell-description">
            <div class="flex-box-row order-cell-title">
                <p class="title">{{item.sn}}</p>
                <p class="money">¥{{item.money}}</p>
            </div>
            <span class="info">
                设备:{{item.pay_device}}/{{item.alias}} <br>
                支付类型:{{item.pay_type}} <br>
                下单时间:{{item.trxdate}} <br>
                支付时间:{{item.pay_time}} <br>
                订单状态:{{item.status}}
            </span>
        </div>
    </div>
</scroller>

只有在刚进入页面的时候会触发一次(但是又和mounted重复了),之后便不会再触发

SyntaxError: Unexpected token

image
"vue": "^2.1.8",
"webpack": "^2.1.0-beta.25",

我测试下来
import Scroller from './components/Scroller.vue'
export default Scroller(这里要加;分号)
window.Scroller = Scroller
@wangdahoo
作者你更新下吧!

列表回弹机制

如果列表已经到达最底部,手指按住屏幕一直往上滑动直到移动到屏幕外面也不松开那么列表就不会自动回到原来的位置了

很棒

做的很棒 希望可以更加完善,主要是加载样式自定义程度希望可以更高

关于scroller作为组件被引入到其他组件报错的问题

A组件模板 FeedList 为组件B

<template>
 <FeedList/>
</template>
import FeedList from 'xxx';
const FeedList = {
  components: {
    FeedList
 }
}

B组件模板 Feed 为组件C

<template>
    <scroller 
      style="top: 55px"
      delegate-id="myScroller"
      :on-refresh="refresh"
      :on-infinite="infinite"
      ref="my_scroller"
      :animating="true"
    >
      <div class="feed-list">
        <Feed v-for="feed in feeds" :feed="feed" :key="feed.id"></Feed>
      </div>
    </scroller>
</template>

js

import Scroller from 'vue-scroller';
import Feed from 'xxx';
components: {
      Scroller,
      Feed
    },

场景是这样的
现有3个组件 暂且分别叫做 A,B,C
B组件为包含scroller的组件,B为A的子附件, B拥有子组件 Feed,作为内容循环的载体
父组件中 feed-list中内容为循环服务端请求到的数据
animating如果设置为true,
模板更新后 会提示

Uncaught TypeError: Cannot read property 'Animate' of undefined
    at Scroller.__publish (core.js:1319)
    at Scroller.doTouchEnd (core.js:1210)
    at VueComponent.touchEnd (Scroller.vue:382)
    at VueComponent.boundFn [as touchEnd] (vue.esm.js:124)
    at touchend (Scroller.vue?cd1f:15)
    at HTMLDivElement.invoker (vue.esm.js:1658)

是core.effect这个对象不存在

如果设置animating为FALSE
不错出现上述错误,但是页面在scroll的时候,一点都不流畅,滑动多远就滚多远

将demo的代码做为子组件的时候,在挂载的时候 设置resize则会报错
Uncaught TypeError: Cannot read property 'resize' of undefined

还请指点迷津
谢谢

License statement

@wangdahoo
Hi, thanks for creating this great component!
Is it possible to include a license to clarify the status of this project?

vue 2.1.6 使用问题 : Unknown custom element: <scroller>

  • vue 版本是 2.1.6
  • 按照 demo 的方式使用报错如下
[Vue warn]: Unknown custom element: <scroller> - did you register the component correctly? For recursive components, make sure to provide the "name" option. 
(found in anonymous component at 

How to click in vue-scroller comp

<div ref="imgWrapper"> <div class="img-container" @click="show"> <img class="img" src="http://pic.to8to.com/live/day_170121/20170121_a7ebc40508d40fdbfb98br7EgakxkSFN.jpg"> <img class="img" src="http://pic.to8to.com/live/day_170121/20170121_8a8719ef2f807f6332c9I8gI3v9AZe6l.jpg"> <img class="img" src="http://pic.to8to.com/live/day_170121/20170121_9f90855c39a463fc4655BpZgF0phNaxd.jpg"> <img class="img" src="http://pic.to8to.com/live/day_161215/20161215_0aa7e64b0ec919c5f80dvS4ffTLwj9YD.jpg"> </div> </div>

can't click

demo最下边几行数据不能正常显示

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, user-scalable=no">
   <script src="../plugins/vue/vue.min.js"></script>
  <script src="../plugins/vue/vue-scroller.min.js"></script>
  <title>Vue Scroller</title>
  <style>
    html, body {
      margin: 0;
    }

    * {
      box-sizing: border-box;
    }

    .row {
      width: 100%;
      height: 50px;
      padding: 10px 0;
      font-size: 16px;
      line-height: 30px;
      text-align: center;
      color: #444;
      background-color: #fff;
    }

    .grey-bg {
      background-color: #eee;
    }

    .header {
      position: fixed;
      top: 0;
      left: 0;
      height: 44px;
      width: 100%;
      box-shadow: 0 2px 10px 0 rgba(0,0,0,0.1);
      background-color: #fff;
      z-index: 1000;
      color: #666;
    }

    .header > .title {
      font-size: 16px;
      line-height: 44px;
      text-align: center;
      margin: 0 auto;
    }
  </style>
</head>
<body>
<div id="app">
  <div class="header">
    <h1 class="title">Refresh & Infinite</h1>
  </div>
  <scroller :on-refresh="refresh"
            :on-infinite="infinite"
            ref="my_scroller" style="top: 44px;">
    <div v-for="(item, index) in items" class="row" :class="{'grey-bg': index % 2 == 0}">
      {{ item }}
    </div>
  </scroller>
</div>
<script>
  new Vue({
    el: '#app',

    components: {
      Scroller
    },

    data: {
      items: []
    },
    
    mounted: function () {
      for (var i = 1; i <= 20; i++) {
        this.items.push(i + ' - keep walking, be 2 with you.');
      }
      this.top = 0;
      this.bottom = 0;

      setTimeout(() => {
        this.$refs.my_scroller.resize();
      })
    },

    methods: {
      refresh: function () {
        setTimeout(() => {
          var start = this.top - 1
          for (var i = start; i > start - 10; i--) {
            this.items.splice(0, 0, i + ' - keep walking, be 2 with you.');
          }
          this.top = this.top - 10;
          this.$refs.my_scroller.finishPullToRefresh();
        }, 1500)
      },

      infinite: function () {
        setTimeout(() => {
          var start = this.bottom + 1;
          for (var i = start; i < start + 10; i++) {
            this.items.push(i + ' - keep walking, be 2 with you.');
          }
          this.bottom = this.bottom + 10;

					if(this.bottom>40){
          	  this.$refs.my_scroller.finishInfinite(true);
					}else
					{
						setTimeout(() => {
            this.$refs.my_scroller.finishInfinite();
         		 })
					}
          
        }, 1500)
      }
    }
  });
</script>
</body>
</html>

使用vue-scroller保持scrolltop值的问题

请教下大神 我用了这个组件
列表上拉加载了更多之后 点击列表进入子页面,或者切换view, 然后返回
vue-scroller的页面translate3d(0px, 0px, 0px)的Y值还原变成0了 这怎么解决饿

设置了高度,调用了resize()还是无法滚动

我做的一个目录组件,从父组件得到目录数据,然后渲染出一个目录列表,这渲染出的目录只能在一屏的高度内弹动,无法滚动到最低部,我在beforeUpdate中设置好scroll父元素的高度还是不行,请问我的使用方法错了吗

<template>
    <div class="catalog-mask" @click.stop="closeCatalog">
        <div class="catalog-container" :style="{height: catalogHeight + 'rem'}">
            <Scroller ref="scroller">
                <div>
                    <div class="catalog-container__count">共{{this.catalogData.length}}章</div>
                    <div v-for="(item, index) of this.catalogList" 
                        :key="item.articleId"
                        class="catalog-container__item"
                        :class="item.current ? 'current' : ''"
                        @click.stop="selectCatalog(item.articleId)">
                        {{item.title}}
                    </div>
                </div>
            </Scroller>
        </div>
    </div>
</template>

<script>
import Scroller from 'vue-scroller';
export default {
    data () {
        return {
            catalogHeight: 0,
        }
    },
    props: ['catalogData', 'articleId'],
    components: {
        Scroller,
    },
    mounted(){
    },
    beforeUpdate(){
        this.catalogHeight = this.catalogData.length;
    },
    updated(){
        setTimeout(() => {
            this.$refs.scroller.resize();
            console.log('resize');
        }, 2000)
    },
    computed:{
        catalogList(){
            let temp = this.catalogData.map((item, index) => {
                if(item.articleId === this.articleId){
                    item.current = true;
                }
                return item;
            })
            return temp;
        }
    },
    methods: {
        selectCatalog(articleId){
            this.$emit('selectCatalog', articleId);
        },
        closeCatalog(){
            this.$emit('closeCatalog');
        },
        getPrev(){

        },
        getNext(){

        },
    },
}
</script>

<style lang="scss">
    .catalog-mask{
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        background: rgba(0,0,0, .3);
        z-index: 11;
    }
    .catalog-container{
        min-height: 100%;
        background: #FFF;
        margin-right: .9rem;
        position: relative;
    }
    .catalog-container__count{
        margin-left: .5rem;
        margin-right: .9rem;
        height: .82rem;
        line-height: 1.2rem;
        font-size: .26rem;
        color: #B3B3B3;
    }
    .catalog-container__item{
        margin-left: .5rem;
        margin-right: .9rem;
        height: 1rem;
        font-size: .3rem;
        color: #545454;
        line-height: 1rem;
        border-bottom: 1px solid #ECECEC;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
    }
    .catalog-container__item:active{
        color: #ccc;
    }
</style>

调用scrollTo(null,0,true)时,会出现无效的情况

版本 0.4.0
使用以下代码,调用的时候,必须要等待滑动事件结束之后,才可以调用,会出现延迟的情况,感觉上就像要点击2次,才能scrollTo指定的位置。
调用getPosition() 打印出来是之前的位置,比如从顶部滚动到底部的时候,getPosition() 获取的值是 0 ,0 。

back2Top(){
            this.$refs.my_scroller.getPosition()
            this.$refs.my_scroller.scrollTo(null, 0, true)
        },

卡顿

您好,我测试了四个手机,滑动感觉卡顿,三个ios,两个安卓。 自己写的和你的demo都有测,在安卓上卡顿卡顿更明显,感觉就像丢帧一样。
然后又测了一下vonic中的scroll组件,这个不卡。

进入页面会触发一次infinite

进入页面会触发一次infinite,
如果不finishInfinite那么拉到页面底部就不会执行infinite,
如果finishInfinite的话,下拉到页面底部会不断执行infinite,
麻烦看下这个问题哈 @wangdahoo

Cant use directly with webpack 2 and vue 2, throw "Couldn't find preset 'es2015'"

Condition

[email protected]
[email protected]
[email protected]
[email protected]

My step:

  1. npm install vue-scroller
  2. import Scroller from 'vue-scroller' ( in my vue component )
  3. declare components object components: {Scroller} ( in my vue component )
  4. write html <scroller><div v-for="..."></div></scroller>
  5. preview

Then

Module build failed: Error: Couldn't find preset "es2015" relative to directory "/Users/jonas/Documents/VoyageOne/offshore2/offshore-mobile/client-webchat/src/main/webapp/node_modules/vue-scroller"

And

I see your babelrc in your demo

Maybe you need a "per-dependency" in your package.json

如果新建的是webpack项目会报Unexpected token import 错误

按帮助创建webpack-simple项目的话修改webpack.conf.js启动项目没有问题,但是使用webpack创建项目的话,在build/webpack.base.conf 中添加 vue-scroller的loaders,但是在进入node_modules时babel没有转换src/index.js导致了该错误

webpack 2.0项目跑不了

使用webpack 2.0 会报错 Failed to mount component: template or render function not defined.
(found in component )

请教一个问题,关于引入组件报错

我npm下载你的组件到我的项目里,我引用后会报一个错误
[Vue warn]: Failed to mount component: template or render function not defined. (found in component <scroller>) 这是代码:

<template>
      <div>
              <header-module></header-module>
              <div class="scrollN container bgImage" style="top:42px; height:auto;">
                      <scroller style="top:42px; height:auto;"
                      :on-refresh="refresh"
                      :on-infinite="infinite"
                      ref="my_scroller">
                      </scroller>
               </div>
        </div>
</template>
<script>
    import HeaderComponent from '../components/header-module.vue'
    import Scroller from 'vue-scroll'
    import FooterComponent from '../components/footer-module.vue'
    import oHttp from '../js/http.js'

    export default{

        components:{
            "header-module":HeaderComponent,
            "footer-module":FooterComponent,
            Scroller
        },
        ... ...

非常感谢

使用npm集成时候,引用会出现问题

使用npm集成的时候,引用会出现了问题,因为package.json里面的"main"值是"src/index.js",而index.js是使用es6开发的。

import Scroller from './components/Scroller.vue'
export default Scroller

我的wabpack不会去解析es6的代码,所以会报错

和vue-resource用有问题

用vue-resource加载数据 程序先加载完mounted里面的数据还没开始滚动屏幕马上又加载了infinite的数据 并没有像demo一样正常加载滚动以后再加载

mounted() {
this.$http.get('/static/data/banner.json').then((response) => {
for(let i = 0 ; i < 10 ; i++ ){
this.items.push(response.body.card[i])
}
},function(){
console.log('error')
})
this.top = 1
this.bottom = 10
setTimeout(() => {
this.$refs.my_scroller.resize()
console.log('one')
})
},
methods: {
infinite() {
if (this.bottom >= 28) {
setTimeout(() => {
this.$refs.my_scroller.finishInfinite(true)
}, 1500)
return;
}
setTimeout(() => {
let start = this.bottom
let all = start + 10
if(all>=28){
all = 28
}
this.$http.get('/static/data/banner.json').then((response) => {
for(let i = start ; i < all ; i++ ){
this.items.push(response.body.card[i])
}
},function(){
console.log('error')
})
this.bottom = this.bottom +10;
setTimeout(() => {
this.$refs.my_scroller.finishInfinite()
})
}, 1500)
},

}

infinite不会触发

我发现一个问题。
在页面刚加载进来的时候infinite会触发一次
之后滑倒底部就不会再触发了。

我怎么添加回到顶部的功能?

版本 0.4.0
现在实现了一个体验不好的版本,即增加一个scrollingComplete的回掉方法,但是延迟很高,尤其是在“减速滑动”的时候,有没有更好的解决方案?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.