返回

手把手教你打造首页频道列表,让用户爽滑到底!

前端

一、基本结构
一个典型的频道列表由以下几个部分组成:

  1. 频道导航栏:用于显示所有频道,并允许用户在不同频道之间切换。
  2. 频道内容区:用于显示当前频道的内容。
  3. 分页器:用于控制当前显示的内容页。

我们使用Vue.js和vant库来构建频道列表。首先,我们需要创建一个Vue组件来表示频道导航栏。

<template>
  <div class="channel-nav">
    <van-nav-bar
      :value="activeChannel"
      @change="changeChannel"
    >
      <van-nav-bar-item v-for="channel in channels" :key="channel.id" :title="channel.name" />
    </van-nav-bar>
  </div>
</template>

<script>
export default {
  props: {
    channels: {
      type: Array,
      required: true
    },
    activeChannel: {
      type: String,
      required: true
    }
  },
  methods: {
    changeChannel(channel) {
      this.$emit('change-channel', channel)
    }
  }
}
</script>

<style>
.channel-nav {
  background-color: #fff;
}
</style>

接下来,我们需要创建一个Vue组件来表示频道内容区。

<template>
  <div class="channel-content">
    <div v-for="item in channelData" :key="item.id">
      {{ item.title }}
    </div>
  </div>
</template>

<script>
export default {
  props: {
    channelData: {
      type: Array,
      required: true
    }
  }
}
</script>

<style>
.channel-content {
  padding: 10px;
}
</style>

最后,我们需要创建一个Vue组件来表示分页器。

<template>
  <div class="paginator">
    <van-pagination
      :total="totalPage"
      :current="currentPage"
      @change="changePage"
    />
  </div>
</template>

<script>
export default {
  props: {
    totalPage: {
      type: Number,
      required: true
    },
    currentPage: {
      type: Number,
      required: true
    }
  },
  methods: {
    changePage(page) {
      this.$emit('change-page', page)
    }
  }
}
</script>

<style>
.paginator {
  text-align: center;
  margin-top: 10px;
}
</style>

二、获取频道并显示

现在,我们已经创建了三个Vue组件,接下来我们需要将它们组合起来,并在页面上显示频道列表。

<template>
  <div class="channel-list">
    <channel-nav
      :channels="channels"
      :active-channel="activeChannel"
      @change-channel="changeChannel"
    />
    <channel-content :channel-data="channelData" />
    <paginator
      :total-page="totalPage"
      :current-page="currentPage"
      @change-page="changePage"
    />
  </div>
</template>

<script>
export default {
  data() {
    return {
      channels: [],
      activeChannel: '',
      channelData: [],
      totalPage: 0,
      currentPage: 1
    }
  },
  created() {
    this.getChannels()
  },
  methods: {
    getChannels() {
      // 获取频道列表
      this.channels = [
        { id: '1', name: '频道1' },
        { id: '2', name: '频道2' },
        { id: '3', name: '频道3' }
      ]
    },
    changeChannel(channel) {
      // 切换频道
      this.activeChannel = channel.id
      this.currentPage = 1
      this.getChannelData()
    },
    getChannelData() {
      // 获取频道数据
      this.channelData = [
        { id: '1', title: '文章1' },
        { id: '2', title: '文章2' },
        { id: '3', title: '文章3' }
      ]
      this.totalPage = 3
    },
    changePage(page) {
      // 切换页码
      this.currentPage = page
      this.getChannelData()
    }
  }
}
</script>

<style>
.channel-list {
  width: 100%;
  height: 100%;
}
</style>

三、设置滚动条的样式并使用全局样式覆盖vant库的样式

现在,我们的频道列表已经能够正常工作了。但是,滚动条的样式不太美观。我们可以使用CSS来设置滚动条的样式。

/* 设置滚动条的样式 */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
  background-color: #f5f5f5;
}

/* 设置滚动条滑块的样式 */
::-webkit-scrollbar-thumb {
  background-color: #ccc;
  border-radius: 4px;
}

/* 设置滚动条滑块悬停时的样式 */
::-webkit-scrollbar-thumb:hover {
  background-color: #999;
}

此外,我们还可以使用全局样式来覆盖vant库的样式。

/* 全局样式 */
.van-nav-bar {
  background-color: #f5f5f5;
}

.van-nav-bar-item {
  color: #333;
}

.van-nav-bar-item.van-nav-bar-item--active {
  color: #000;
}

.van-pagination {
  margin-top: 10px;
}

.van-pagination-item {
  background-color: #fff;
  border-color: #ccc;
  color: #333;
}

.van-pagination-item--active {
  background-color: #ccc;
  color: #fff;
}

四、组件的数据加载机制

我们的频道列表已经基本完成。但是,我们还需要考虑组件的数据加载机制。

当用户第一次访问页面时,我们需要加载频道列表和频道数据。我们可以使用Vuex来管理这些数据。

// store/index.js
import Vuex from 'vuex'
import Vue from 'vue'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    channels: [],
    channelData: [],
    totalPage: 0,
    currentPage: 1
  },
  mutations: {
    setChannels(state, channels) {
      state.channels = channels
    },
    setChannelData(state, channelData) {
      state.channelData = channelData
    },
    setTotalPage(state, totalPage) {
      state.totalPage = totalPage
    },
    setCurrentPage(state, currentPage) {
      state.currentPage = currentPage
    }
  },
  actions: {
    getChannels({ commit }) {
      // 获取频道列表
      const channels = [
        { id: '1', name: '频道1' },
        { id: '2', name: '频道2' },
        { id: '3', name: '频道3' }
      ]
      commit('setChannels', channels)
    },
    getChannelData({ commit, state }) {
      // 获取频道数据
      const channelData = [
        { id: '1', title: '文章1' },
        { id: '2', title: '文章2' },
        { id: '3', title: '文章3' }
      ]
      commit('setChannelData', channelData)
      commit('setTotalPage', 3)
    }
  }
})

在组件中,我们可以使用Vuex来获取数据。

// ChannelList.vue
export default {