Home  >  Article  >  Web Front-end  >  How to use Vue to implement a page design similar to Zhihu Daily?

How to use Vue to implement a page design similar to Zhihu Daily?

WBOY
WBOYOriginal
2023-06-25 12:08:041973browse

Vue.js is a front-end framework based on the MVVM pattern. It decouples data and UI pages through data binding and componentization, making web development more efficient and simpler. Zhihu Daily is a news client with beautiful UI design, powerful interactivity and content diversity. In this article, we will use Vue technology to implement a page design that mimics Zhihu Daily.

  1. Build the environment

Before we start, we need to install Node.js and Vue-cli. After installing Node.js, use the command line tool to run the following command in the terminal to install Vue-cli:

$ npm install -g vue-cli

After the installation is complete, use Vue-cli to create a project based on the webpack template:

$ vue init webpack vue-zhihudaily

At this point, we can see that after create a new project asks you several questions (project name, description, author, whether eslint code specifications are required, etc.), a folder named vue-zhihudaily will be created in the current directory as a project Root directory.

  1. Page layout

In Zhihu Daily, it is mainly divided into three pages: homepage, article list page and article details page. Here we take the homepage as an example . In the src folder, create a views folder to store the interface files. Create the Home.vue file with the following code:

<template>
  <div class="home">
    <div class="banner"></div>
    <div class="daily-list"></div>
  </div>
</template>

<style scoped>
.home {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.banner {
  width: 100%;
  height: 200px;
  background: linear-gradient(to bottom, #ffffff, #f5f5f5);
}
.daily-list {
  width: 100%;
  height: 100%;
}
</style>

Here, we use flex layout to vertically center the page. Among them, banner is used to display carousel images, and daily-list is used to display article lists.

  1. Using components

In order to facilitate reuse and maintenance, we use Vue componentization to build the interface. In the src folder, create a components folder to store component files. Within it, create a file called DailyItem.vue:

<template>
  <div class="daily-item">
    <div class="thumbnail">
      <img :src="item.images[0]" alt="">
    </div>
    <div class="info">
      <div class="title">{{item.title}}</div>
      <div class="date">{{item.date}}</div>
    </div>
  </div>
</template>

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

<style scoped>
.daily-item {
  width: 100%;
  height: 80px;
  display: flex;
  align-items: center;
  margin-bottom: 5px;
  padding: 0 10px;
  box-sizing: border-box;
  background: #ffffff;
}
.daily-item:hover {
  cursor: pointer;
}
.thumbnail {
  width: 80px;
  height: 60px;
  margin-right: 10px;
  overflow: hidden;
}
.thumbnail img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.info {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.title {
  font-size: 16px;
  color: #444444;
  margin-bottom: 5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.date {
  font-size: 12px;
  color: #999999;
}
</style>

DailyItem.vue is used to display information from the article list, including article thumbnails, titles, and dates. Here, we use the props attribute to pass the article information into the component. Use the DailyItem.vue component in Home.vue and replace daily-list with:

<div class="daily-list">
  <daily-item v-for="(item, index) in dailyList" :key="index" :item="item"></daily-item>
</div>

When there are multiple daily reports, this component will automatically render a DailyItem.vue for each daily report. In the parent component home, pass dailyList to the child component DailyItem.vue through props.

  1. Carousel chart implementation

The carousel chart imitating Zhihu Daily is an important part of this page. In the src folder, create a component named Banner.vue:

<template>
  <div class="banner">
    <swiper :options="swiperOption" ref="mySwiper">
      <swiper-slide v-for="(item, index) in bannerList" :key="index">
        <img :src="item.image" alt="">
        <div class="text">{{item.title}}</div>
      </swiper-slide>
      <div class="swiper-pagination" slot="pagination"></div>
    </swiper>
  </div>
</template>

<script>
import { Swiper, SwiperSlide, Pagination } from 'swiper/dist/js/swiper.esm.js'
import 'swiper/dist/css/swiper.css'

export default {
  data () {
    return {
      swiperOption: {
        pagination: {
          el: '.swiper-pagination'
        },
        loop: true,
        autoplay: {
          delay: 3000
        }
      }
    }
  },
  props: ['bannerList'],
  mounted () {
    Swiper.use([Pagination])
    this.$refs.mySwiper.swiper.slideTo(0)
  },
  components: {
    Swiper,
    SwiperSlide,
    Pagination
  }
}
</script>

<style scoped>
.banner {
  width: 100%;
  height: 200px;
  background: linear-gradient(to bottom, #ffffff, #f5f5f5);
}
.swiper-pagination-bullet-active {
  background-color: #ffffff;
}
.text {
  position: absolute;
  bottom: 10px;
  left: 10px;
  font-size: 16px;
  color: #ffffff;
  text-shadow: 1px 1px 0px rgba(0, 0, 0, 0.3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
</style>

In Banner.vue, we use the Swiper third-party library to build the carousel chart. Call swiper.slideTo(0) in the mounted hook function to realize that the initial page is the first carousel image.

Use the Banner.vue component in Home.vue:

<div class="banner">
  <banner :bannerList="bannerList"></banner>
</div>

Here, use props to pass the bannerList into the Banner.vue component.

  1. Data acquisition

In Zhihu Daily, the homepage needs to display an article list and carousel image. We use the axios library to initiate a GET request to the Zhihu Daily API to obtain the data of the carousel chart and article list. Under the src folder, create a folder named api, and create a zhihudaily.js file in it:

import axios from 'axios'

// 轮播图 API
const bannerApi = 'https://news-at.zhihu.com/api/4/news/latest'

// 文章列表 API
const articleListApi = 'https://news-at.zhihu.com/api/4/news/before/'

export default {
  // 获取轮播图
  async getBanner () {
    const { data } = await axios.get(bannerApi)
    return data.top_stories
  },

  // 获取文章列表
  async getArticleList (date) {
    const { data } = await axios.get(articleListApi + date)
    return data.stories
  }
}

Call the method in the api in Home.vue and pass in the obtained data Among the corresponding props:

<script>
import api from '../api/zhihudaily'
import DailyItem from '../components/DailyItem.vue'
import Banner from '../components/Banner.vue'

export default {
  data () {
    return {
      bannerList: [],
      dailyList: []
    }
  },
  components: {
    DailyItem,
    Banner
  },
  async mounted () {
    this.bannerList = await api.getBanner()
    this.dailyList = await api.getArticleList('')
  }
}
</script>

Through the async/await syntax, we can obtain the required data asynchronously, making the page more efficient.

  1. Conclusion

In this article, we use Vue technology to implement a page design that imitates Zhihu Daily, involving components, carousels, and data acquisition. Waiting for knowledge points. Component-based development allows developers to better maintain and expand code, and uses third-party libraries (such as Swiper, axios) to quickly implement functions, making development more efficient.

Only by continuously expanding your knowledge base, broadening your horizons, and constantly exploring can you go further on the road to web development.

The above is the detailed content of How to use Vue to implement a page design similar to Zhihu Daily?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn