Vue.js Library!利用ScrollView再次打造infinite scrolling功能吧!(30 Days challenge-23)

前言

還記得在day20的時候我們利用vanilla.js打造無限捲動的post嗎?前幾天剛好看到助教群中也有人討論到相關的主題,於是就想到用vue做出類似的效果,果不其然…比自己寫JS快多了XD,利用scroll-view真的會極端輕鬆的達成目的!

使用技術

ScrollView基本介紹

ScrollView是一個vue.js使用的plugin,可以幫助你在各種元件中監聽scroll行為並輕易作出一些常見的效果,比方說本篇文章要介紹的infinite scrolling,或是medium上常見的lazy loader效果,當然也可以透過ScrollView做出一些動畫效果,是個能加強你專案UI與互動性的好幫手。

ScrollView使用

首先自然是透過npm或是yarn指令安裝scrollview

npm install vue-scrollview

接著在你的專案入口(如果你用vue-cli,那就是src/main.js)載入scrollview

import ScrollView from 'vue-scrollview'
Vue.use(ScrollView)

這個行為會在全域建造<Scroll-view />這樣的component供你使用。基本用法的部分可以參照官方文件

大體上來說<Scroll-view />由以下幾個要素所構成。

  • key,Scroll-view中必備的元素,且由於Scroll-view會是全域的組件,所有的key值必須是唯一值
  • slot-scope="visibility",visibility其實只是個單純的物件,可以是任何名字,裡面的值則是透過上方建立的key值做設定。

基本在父層元件會是類似以下的結果

<Scroll-view>
    <template slot-scope="visibility">
        <my-component key="a" :visible="visibility.a"></my-component>
    </template>
</Scroll-view>

Infinite scrolling

scroll view要達成infinite scrolling真的相當的輕鬆,這邊是官網給的示範,利用imageplace holderAPI做的簡易demo,要完成以下demo,首先在父層的部份你需要建立Scroll-view component

App.vue

<template>
  <div id="app">
    <h1>Infinite scrolling using scroll-view</h1>
    <Scroll-view>
      <template slot-scope="visible">
        <my-component v-for="i in items" :source="i.url" :key="i.id"></my-component>
      </template>
    </Scroll-view>
    <h3 v-if="loading" class="loading">Loading...</h3>
  </div>
</template>

並在script的部份先載入$scrollview屬性,$scrollview提供了幾個function判斷scroll事件,今天要用的是onLastEntered,也就是當捲動到最後一個元素時將會觸發你指定的callback,詳情可以見官方文件

import ComponentA from '@/components/ComponentA.vue' // 自己建立的image元件
import axios from 'axios' // 你也可以使用原生的fetch
import { $scrollview } from 'vue-scrollview'

App.vue完整程式碼如下

<template>
  <div id="app">
    <h1>Infinite scrolling using scroll-view</h1>
    <Scroll-view>
      <template slot-scope="visible">
        <my-component v-for="i in items" :source="i.url" :key="i.id"></my-component>
      </template>
    </Scroll-view>
    <h3 v-if="loading" class="loading">Loading...</h3>
  </div>
</template>

<script>
import ComponentA from '@/components/ComponentA.vue'
import axios from 'axios'
import { $scrollview } from 'vue-scrollview'

export default {
  name: 'App',
  components: {
    'my-component': ComponentA
  },
  data() {
    return {
      page: 1,
      items: [],
      loading: false
    }
  },
  watch: {
    page: {
      immediate: true,
      handler: function () {
        // get some more items every time the page changes
        this.fetchMore()
      }
    }
  },
  methods: {
    fetchMore() {
      this.loading = true
      axios.get(`https://jsonplaceholder.typicode.com/albums/${this.page}/photos`)
        .then(({ data }) => {
          this.loading = false
          this.items = this.items.concat(data.slice(1, 6))
        })
    },
  },
  mounted() {
    $scrollview.onLastEntered = () => this.page++ // last component entered, increment the page
  }
}
</script>

<style>
h1,
.loading {
  text-align: center;
}
</style>

子元件的部分則相當的單純,基本上就只是一個img元件,利用從父層接收到的source屬性做圖片的顯示。

ComponentA.vue

<template>
  <div class="scroll-image">
    <img :src="source" alt="a placeholder scroll image" />
  </div>
</template>

<script>
export default {
  props: ['source']
}
</script>

<style>
.scroll-image {
  margin: 0 auto 400px;
  max-width: 600px;
}
</style>

這樣就可以完成Infinite scrolling囉~!太簡單了對吧!

專案預覽

專案連結

github
demo

發表留言