大三學生的第二個基於 React 框架的輪播圖元件。

fengjiangjun發表於2019-04-09

在之前文章中介紹了使用原生 JS 實現輪播圖外掛的過程,大家可以點選這裡去檢視,本文介紹一下基於 React 框架的輪播圖實現。

目前在找實習工作,有合適的機會希望小夥伴們多多推薦~

概要

本文主要講述一個基於 React 的Slider 元件的開發過程,有些地方可能會比較囉嗦,大神可以忽略~

雖然是一個小小的輪播圖元件,但是我還是希望將它作為一個完整的專案進行對待。

完整的開發過程如下:

  • 專案背景
  • 產品需求
  • 開發需求
  • 實現過程
  • 提交程式碼
  • 釋出
  • 小結

專案背景

現代Web專案的開發使用的技術棧一般不會採用原生 JS 或者基於 Jquery 進行刀耕火種式的開發,而是使用 React 或者 Vue 框架。 由於我們是基於 React 框架實現該輪播元件,所以我們需要在 React 的規則之內進行開發。那麼,至少我們需要熟悉 React 的使用以及元件開發過程。

React 的使用

React 是一個 MVVM 框架,擁有很多功能,但核心思想卻很明確。

React 的核心是資料驅動檢視以及元件化思想,所以我們最常用到的就是:

  • 通過 setState 改變狀態,同時驅動檢視更新。
  • 將父元件中的資料通過 props 傳遞給子元件,完成父子資料傳遞。
  • 將頁面拆分成一個又一個的功能元件,然後將元件拼成一個個完整的模組,最終組裝成一個頁面。

使用 React 開發元件

使用 React 開發元件,那麼少不了 Webpack,我們需要接入 Babel 轉譯 ES6 和 jsx 語法。

產品需求

產品需求和大三學生的第一個輪播圖元件一樣。

  • 能夠實現自左向右的輪播。
  • 輪播到最後一張圖時,能夠無縫銜接到第一張圖。
  • 點選圖片能夠跳轉到對應連結。
  • 點選縮略圓點能夠滾動到對應圖片。

開發需求

開發需求也和大三學生的第一個輪播圖元件一樣。

  • 支援圖片和點選連結的可配置。
  • 支援輪播持續時間的配置。
  • 支援輪播間隔時間的配置。
  • 支援輪播圖顯示容器的配置。
  • 支援縮略圓點的顏色、啟用顏色、半徑、距離底部位置的配置。

實現

  • 首先,在 github 上建立一個倉庫react-slider
  • 將 github 建立好的倉庫拉取到本地。
    git clone 【倉庫地址】
    複製程式碼
  • 進入本地目錄
    cd react-slider
    複製程式碼
  • 初始化 npm 倉庫
    npm init
    複製程式碼
  • 編寫 Webpack 配置 我們使用 html-webpack-plugin 打包 demo 頁面,用 webpack-dev-server在本地啟動一個伺服器快速除錯,同時支援 sassless 語法支援。

完整的 webpack.config.js 配置如下:

    const path = require("path");
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const htmlWebpackPlugin = new HtmlWebpackPlugin({
        template: path.join(__dirname, "demo/demo.html"),
        filename: "./index.html"
    });
    module.exports = {
        entry: path.join(__dirname, "demo/demo.js"),
        output: {
        path: path.join(__dirname, "./dist"),
        filename: "dist.js"
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                use: "babel-loader",
                exclude: /node_modules/
            },
            {
                test: /\.css$/,
                use: ["style-loader", "css-loader"]
            },
            {
                test: /\.scss$/,
                use: ["style-loader", "css-loader", "sass-loader"]
            },
            {
                test: /\.less$/,
                use: ["style-loader", "css-loader", "less-loader"]
            }
        ]
    },
    plugins: [htmlWebpackPlugin],
    resolve: {
        extensions: [".js", ".jsx"]
    },
    devServer: {
        port: 3001
    }
};
複製程式碼
  • 安裝依賴 為了滿足以上 webpack 配置的功能,我們需要安裝一些依賴:
{
  "name": "react-slider-fjj",
  "version": "0.0.1",
  "description": "react-slider",
  "main": "./dist/slider.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack-dev-server --mode=development",
    "demo": "webpack --config ./webpack.config.js --progress --colors",
    "build": "babel slider -d dist --copy-files"
  },
  "author": "fengjiangjun",
  "license": "ISC",
  "devDependencies": {
    "babel": "^6.23.0",
    "babel-cli": "^6.26.0",
    "babel-core": "~6.26.0",
    "babel-loader": "^7.1.5",
    "babel-preset-env": "^1.7.0",
    "babel-preset-react": "^6.24.1",
    "css-loader": "^2.1.0",
    "html-webpack-plugin": "^3.2.0",
    "less": "^3.9.0",
    "less-loader": "^4.1.0",
    "source-list-map": "^2.0.1",
    "style-loader": "^0.23.1",
    "watchpack": "^1.6.0",
    "webpack": "^4.29.5",
    "webpack-cli": "^3.2.3",
    "webpack-dev-server": "^3.2.1"
  },
  "dependencies": {
    "react": "^16.8.3",
    "react-dom": "^16.8.3"
  }
}
複製程式碼

注意,由於 npm 是國外伺服器,安裝過程可能會比較慢,為了提高安裝速度,我們需要將 npm 源改成國內映象,目前使用最廣泛的就是淘寶映象,我們改一下。

npm config set registry http://registry.npmjs.taobao.org
複製程式碼

這樣,在執行npm包的安裝操作時,速度會大大提升。

執行安裝命令

npm install
複製程式碼
  • 做好了準備工作,接下來開始編碼實現了。 輪播圖的主要難點在於如何在圖片輪播到最後一張時無縫切換到第一張,這個細節在上一篇大三學生的第一個輪播圖元件中已經進行了講解,所以本文就不再做詳細描述啦,感興趣的話,大家可以檢視上一篇哈~

貼一下主要程式碼:

import React from 'react';
import './index.css';
export default class extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      index: 1
    }
    this.container = React.createRef();
    this.imgWrapper = React.createRef();
    this.list = this.props.list;
    //將圖片陣列的第一張圖放到陣列最後,通過此方法 hack 無縫輪播。
    this.list.push(this.props.list[0]);
  }
  componentDidMount () {
    if (!this.list) {
      return;
    }
    this.container.current.style.width = this.props.width + "px";
    this.container.current.style.height = this.props.height + "px";
    this.imgWrapper.current.style.height = this.props.height + "px";
    const count = this.list.length;
    this.imgWrapper.current.style.width = count * this.props.width + 'px';
    this.time = setTimeout(this.loop.bind(this), this.props.intervalTime || 2000);
    this.imgWrapper.current.addEventListener('transitionend', () => {
      this.time = setTimeout(this.loop.bind(this), this.props.intervalTime || 2000);
      if (this.state.index == count) {
        this.imgWrapper.current.style.transition = '0s';
        this.imgWrapper.current.style.transform = 'translateX(0px)';
        this.state.index = 1;
      }
    })
  }
  loop () {
    if (this.state.index < this.list.length) {
      this.imgWrapper.current.style.transition = this.props.transitionTime || '2s';
      this.imgWrapper.current.style.transform = 'translateX(' + (-this.state.index * this.props.width) + 'px)';
    }
    this.setState(prevState => ({
      index: prevState.index + 1
    }))
  }
  render () {
    return <div className='container' ref={this.container}><div className='img-wrapper' ref={this.imgWrapper}>
      {this.list.map(item => {
        return <img src={item.text} style={{ width: this.props.width }} className='img-item' onClick={() => { window.open(item.href); }} />

      })}
    </div>
      <div className="round-container">
        {this.list.map(
          (item, index) => {
            if (index == this.list.length - 1) {
              return null;
            }
            if (this.state.index - 1 === index && this.state.index !== (this.list.length)) {
              return <div className="yello"></div>
            }
            if (this.state.index == (this.list.length) && index == 0) {
              return <div className="yello"></div>
            }
            return <div className='red' onClick={() => { clearTimeout(this.time); this.setState({ index: index }); this.time = setTimeout(this.loop.bind(this), 0); }}>
            </div>
          })}
      </div>
    </div>
  }
}
複製程式碼
  • 推送到 github

推送到 github ,比較簡單了,只需幾步簡單的 git 命令即可。

// 儲存本地修改
git add ./
// 提交本次修改
git commit -m ''
// 推送到遠端伺服器。
git push origin master
複製程式碼

但是我們需要為我們的元件增加一個 demo 頁面,所以我們最好能夠將我們的 demo 頁面提供給別人檢視,這裡我們依然採用 github 的功能。

1、首先新建一個分支 gh-pages,這個分支名字是固定的,不可換成其他的,否則產生不了我們的線上預覽頁面。

git checkout -b gh-pages
複製程式碼

2、其次生成本地的demo頁面。

npm run demo
複製程式碼

將 gh-pages 分支內容推送到 github。

3、到 github 網站對應的倉庫上,點選 Settings:

大三學生的第二個基於 React 框架的輪播圖元件。

4、往下翻到 github pages 節點

大三學生的第二個基於 React 框架的輪播圖元件。

看到的這個網址,就是該專案對應的 gh-pages 的根目錄。

經過以上幾個簡單的命令,我們就能夠將本地的 demo 頁面推送到 github 伺服器供別人預覽了。

釋出到 npm 倉庫。

  • 首先,我們要有npm 賬戶,如果沒有,請先去 npm 網站去註冊。 假設 testuser 為你的 npm 賬號。

首次釋出命令如下:

npm adduser testuser
npm publish
複製程式碼

如果之前成功執行過npm adduser,那麼之後的釋出命令僅僅使用 npm publish即可。

經過這兩個簡單的命令,我們就將元件釋出到了npm 倉庫中,此時,其他同學就可以通過npm 安裝該元件進行使用了。

小結

作為一個準前端畢業生,在學習前端過程中勢必會遇到點點滴滴的知識,這些知識點對於以後工作是很有幫助的,有一些是經常會打交道的,比如 git 常用命令,npm 常用命令,所以在此做個總結,希望能給未來的前端開拓者帶來一些幫助。

以上就是 React 版本 Slider 的開發過程,希望能給大家帶來幫助。

相關文章