整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          H5必會 模糊背景同步jQuery旋轉木馬特效源碼

          果圖

          今天給大家帶來的是一款,超酷模糊背景同步jQuery旋轉木馬特效源碼

          大氣的外表,十分適合科技、藝術類的網站。

          也可以適當的修改成自己喜歡的風格!

          文件版源碼可在評論區留言

          廢話不多說上 源碼!

          CSS源碼:

          @font-face {

          font-family: 'icomoon';

          src:url('../fonts/icomoon.eot?rretjt');

          src:url('../fonts/icomoon.eot?#iefixrretjt') format('embedded-opentype'),

          url('../fonts/icomoon.woff?rretjt') format('woff'),

          url('../fonts/icomoon.ttf?rretjt') format('truetype'),

          url('../fonts/icomoon.svg?rretjt#icomoon') format('svg');

          font-weight: normal;

          font-style: normal;

          }

          [class^="icon-"], [class*=" icon-"] {

          font-family: 'icomoon';

          speak: none;

          font-style: normal;

          font-weight: normal;

          font-variant: normal;

          text-transform: none;

          line-height: 1;

          /* Better Font Rendering =========== */

          -webkit-font-smoothing: antialiased;

          -moz-osx-font-smoothing: grayscale;

          }

          body, html { font-size: 100%; padding: 0; margin: 0;}

          /* Reset */

          *,

          *:after,

          *:before {

          -webkit-box-sizing: border-box;

          -moz-box-sizing: border-box;

          box-sizing: border-box;

          }

          /* Clearfix hack by Nicolas Gallagher: http://nicolasgallagher.com/micro-clearfix-hack/ */

          .clearfix:before,

          .clearfix:after {

          content: " ";

          display: table;

          }

          .clearfix:after {

          clear: both;

          }

          body{

          background: #494A5F;

          color: #D5D6E2;

          font-weight: 500;

          font-size: 1.05em;

          font-family: "Microsoft YaHei","宋體","Segoe UI", "Lucida Grande", Helvetica, Arial,sans-serif, FreeSans, Arimo;

          }

          a{ color: rgba(255, 255, 255, 0.6);outline: none;text-decoration: none;-webkit-transition: 0.2s;transition: 0.2s;}

          a:hover,a:focus{color:#74777b;text-decoration: none;}

          .htmleaf-container{

          margin: 0 auto;

          }

          .bgcolor-1 { background: #f0efee; }

          .bgcolor-2 { background: #f9f9f9; }

          .bgcolor-3 { background: #e8e8e8; }/*light grey*/

          .bgcolor-4 { background: #2f3238; color: #fff; }/*Dark grey*/

          .bgcolor-5 { background: #df6659; color: #521e18; }/*pink1*/

          .bgcolor-6 { background: #2fa8ec; }/*sky blue*/

          .bgcolor-7 { background: #d0d6d6; }/*White tea*/

          .bgcolor-8 { background: #3d4444; color: #fff; }/*Dark grey2*/

          .bgcolor-9 { background: #ef3f52; color: #fff;}/*pink2*/

          .bgcolor-10{ background: #64448f; color: #fff;}/*Violet*/

          .bgcolor-11{ background: #3755ad; color: #fff;}/*dark blue*/

          .bgcolor-12{ background: #3498DB; color: #fff;}/*light blue*/

          .bgcolor-20{ background: #494A5F;color: #D5D6E2;}

          /* Header */

          .htmleaf-header{

          padding: 1em 190px 1em;

          letter-spacing: -1px;

          text-align: center;

          background: #66677c;

          }

          .htmleaf-header h1 {

          color: #D5D6E2;

          font-weight: 600;

          font-size: 2em;

          line-height: 1;

          margin-bottom: 0;

          font-family: "Microsoft YaHei","宋體","Segoe UI", "Lucida Grande", Helvetica, Arial,sans-serif, FreeSans, Arimo;

          }

          .htmleaf-header h1 span {

          font-family: "Microsoft YaHei","宋體","Segoe UI", "Lucida Grande", Helvetica, Arial,sans-serif, FreeSans, Arimo;

          display: block;

          font-size: 60%;

          font-weight: 400;

          padding: 0.8em 0 0.5em 0;

          color: #c3c8cd;

          }

          /*nav*/

          .htmleaf-demo a{color: #fff;text-decoration: none;}

          .htmleaf-demo{width: 100%;padding-bottom: 1.2em;}

          .htmleaf-demo a{display: inline-block;margin: 0.5em;padding: 0.6em 1em;border: 3px solid #fff;font-weight: 700;}

          .htmleaf-demo a:hover{opacity: 0.6;}

          .htmleaf-demo a.current{background:#1d7db1;color: #fff; }

          /* Top Navigation Style */

          .htmleaf-links {

          position: relative;

          display: inline-block;

          white-space: nowrap;

          font-size: 1.5em;

          text-align: center;

          }

          .htmleaf-links::after {

          position: absolute;

          top: 0;

          left: 50%;

          margin-left: -1px;

          width: 2px;

          height: 100%;

          background: #dbdbdb;

          content: '';

          -webkit-transform: rotate3d(0,0,1,22.5deg);

          transform: rotate3d(0,0,1,22.5deg);

          }

          .htmleaf-icon {

          display: inline-block;

          margin: 0.5em;

          padding: 0em 0;

          width: 1.5em;

          text-decoration: none;

          }

          .htmleaf-icon span {

          display: none;

          }

          .htmleaf-icon:before {

          margin: 0 5px;

          text-transform: none;

          font-weight: normal;

          font-style: normal;

          font-variant: normal;

          font-family: 'icomoon';

          line-height: 1;

          speak: none;

          -webkit-font-smoothing: antialiased;

          }

          /* footer */

          .htmleaf-footer{width: 100%;padding-top: 10px;}

          .htmleaf-small{font-size: 0.8em;}

          .center{text-align: center;}

          /****/

          .related {

          color: #fff;

          background: #494A5F;

          text-align: center;

          font-size: 1.25em;

          padding: 0.5em 0;

          overflow: hidden;

          }

          .related > a {

          vertical-align: top;

          width: calc(100% - 20px);

          max-width: 340px;

          display: inline-block;

          text-align: center;

          margin: 20px 10px;

          padding: 25px;

          font-family: "Microsoft YaHei","宋體","Segoe UI", "Lucida Grande", Helvetica, Arial,sans-serif, FreeSans, Arimo;

          }

          .related a {

          display: inline-block;

          text-align: left;

          margin: 20px auto;

          padding: 10px 20px;

          opacity: 0.8;

          -webkit-transition: opacity 0.3s;

          transition: opacity 0.3s;

          -webkit-backface-visibility: hidden;

          }

          .related a:hover,

          .related a:active {

          opacity: 1;

          }

          .related a img {

          max-width: 100%;

          opacity: 0.8;

          border-radius: 4px;

          }

          .related a:hover img,

          .related a:active img {

          opacity: 1;

          }

          .related h3{font-family: "Microsoft YaHei", sans-serif;font-size: 1.2em}

          .related a h3 {

          font-size: 0.85em;

          font-weight: 300;

          margin-top: 0.15em;

          color: #fff;

          }

          /* icomoon */

          .icon-htmleaf-home-outline:before {

          content: "\e5000";

          }

          .icon-htmleaf-arrow-forward-outline:before {

          content: "\e5001";

          }

          @media screen and (max-width: 1024px) {

          .htmleaf-header {

          padding: 2em 10% 2em;

          }

          .htmleaf-header h1 {

          font-size:1.4em;

          }

          .htmleaf-links{font-size: 1.4em}

          }

          @media screen and (max-width: 960px) {

          .htmleaf-header {

          padding: 2em 10% 2em;

          }

          .htmleaf-header h1 {

          font-size:1.2em;

          }

          .htmleaf-links{font-size: 1.2em}

          .related h3{font-size: 1em;}

          .related a h3 {

          font-size: 0.8em;

          }

          }

          @media screen and (max-width: 766px) {

          .htmleaf-header h1 {

          font-size:1.3em;

          }

          .htmleaf-links{font-size: 1.3em}

          }

          @media screen and (max-width: 640px) {

          .htmleaf-header {

          padding: 2em 10% 2em;

          }

          .htmleaf-header h1 {

          font-size:1em;

          }

          .htmleaf-links{font-size: 1em}

          .related h3{font-size: 0.8em;}

          .related a h3 {

          font-size: 0.6em;

          }

          }

          index:

          <!DOCTYPE html>

          <html>

          <head>

          <meta charset="UTF-8">

          <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

          <meta name="viewport" content="width=device-width, initial-scale=1.0">

          <title>超酷模糊背景同步jQuery旋轉木馬特效| jQuery特效|手機微信網站特效| 網頁特效庫</title>

          <meta name="keywords" content="SVG特效, 手機微信網站特效, css3動畫, html5特效, 網頁特效" />

          <meta name="description" content="扣丁學堂-專注于HTML5、CSS3、js、jQuery、手機移動端等網頁特效的手機與分享。特效庫始終堅持:無會員、無積分、無限制的“三無原則”。" />

          <link rel="stylesheet" type="text/css" href="css/normalize.css" />

          <link rel='stylesheet prefetch' href='css/slick.min.css'>

          <link rel="stylesheet" type="text/css" href="css/style.css">

          </head>

          <body>

          <div class="section section-project">

          <h2>Project Carousel</h2>

          <div>

          <div>

          <div><img src="img/1.jpg" alt=""/></div>

          <div><img src="img/2.jpg" alt=""/></div>

          <div><img src="img/3.jpg" alt=""/></div>

          <div><img src="img/4.jpg" alt=""/></div>

          <div><img src="img/5.jpg" alt=""/></div>

          <div><img src="img/6.jpg" alt=""/></div>

          <div><img src="img/7.jpg" alt=""/></div>

          <div><img src="img/8.jpg" alt=""/></div>

          <div><img src="img/9.jpg" alt=""/></div>

          </div>

          <div>

          <div>

          <div><img src="img/1.jpg" alt=""/></div>

          <div><img src="img/2.jpg" alt=""/></div>

          <div><img src="img/3.jpg" alt=""/></div>

          <div><img src="img/4.jpg" alt=""/></div>

          <div><img src="img/5.jpg" alt=""/></div>

          <div><img src="img/6.jpg" alt=""/></div>

          <div><img src="img/7.jpg" alt=""/></div>

          <div><img src="img/8.jpg" alt=""/></div>

          <div><img src="img/9.jpg" alt=""/></div>

          </div>

          <div></div>

          </div>

          </div>

          </div>

          <div style="width: 100%; height: auto; line-height: 25px; text-align: center;">

          </div>

          <script src="js/jquery-1.11.0.min.js" type="text/javascript"></script>

          <script src='js/slick.min.js'></script>

          <script type="text/javascript">

          $(".project-detail").slick({

          slidesToShow: 1,

          arrows: false,

          asNavFor: '.project-strip',

          autoplay: true,

          autoplaySpeed: 3000

          });

          $(".project-strip").slick({

          slidesToShow: 5,

          slidesToScroll: 1,

          arrows: false,

          asNavFor: '.project-detail',

          dots: false,

          infinite: true,

          centerMode: true,

          focusOnSelect: true

          });

          </script>

          </body>

          </html>

          于前端性能優化方法有很多,包括:圖片合并、使用緩存、使用CDN、減少重定向、減少請求、壓縮等等。今天就針對減少請求、資源壓縮,給大家推薦一個基于.Net開發的資源合并與壓縮的開源項目。

          在介紹這個項目之前,先問大家一個問題,大家知道一個瀏覽器同域名請求的最大并發數限制是多少嗎?

          在早期的瀏覽器有的是2個、有的是4個,現在市面主流的瀏覽器一般限制數量是6個,手機一般是4個。雖然每個瀏覽器限制數量不一樣,但我們知道的是,當一個頁面同時發起過多的請求,肯定會導致部分請求在等待的

          所以,我們壓縮和合并靜態資源請求數量,對于我們優化性能肯定有好處的。


          項目簡介

          這是一個基于.Net Core開發的,實現壓縮Css、Javascript、Html資源的壓縮、合并功能的組件。通過這個組件我們就可以實現靜態資源的捆綁,實現對js、css、less、scss等靜態資源的自動打包捆綁處理。

          通過將多個文件合并成了一個文件,減少瀏覽器的請求從而實現提升網站的訪問性能的需求。

          特點:

          1、Js壓縮:進行去掉空格,換行,注釋等,格式緊湊,內部方法匿名化,節約存儲空間。

          2、Css壓縮:去掉空格,換行,注釋等,格式緊湊,節約存儲空間。

          3、Html壓縮:壓縮效果可以實現5-10%的壓縮,刪除助手、折疊空白、刪除可選標記(p、li…)、刪除引用的屬性、刪除特定屬性、解碼HTML實體、壓縮內聯樣式和腳本;支持Html5。


          技術架構

          1、平臺:基于.Net Core 4.5、Netstandard2.0開發

          2、開發工具:Visual Studio 2017


          項目結構


          使用方法

          Js文件壓縮

          var result = Uglify.Js("var x = 5; var y = 6;");
          Console.WriteLine(result.Code);   
          // prints: var x=5,y=6


          Css文件壓縮

          var result = Uglify.Css("div { color: #FFF; }");
          Console.WriteLine(result.Code);   
          // prints: div{color:#fff}


          Html文件壓縮

          var result = Uglify.Html("<div>  <p>This is <em>   a text    </em></p>   </div>");
          Console.WriteLine(result.Code);   
          //prints: <div><p>This is <em>a text</em></div>


          文本解析Html

          var result = Uglify.HtmlToText("<div>  <p>This is <em>   a text    </em></p>   </div>");
          Console.WriteLine(result.Code);   
          // prints: This is a text


          Js、Css文件合并請求示例

          app.UseBundling(bundles =>
          {
              bundles.LoadFromConfigFile("/bundleconfig.json", _env.ContentRootFileProvider); // 如果你需要對Bundle Minifier的配置也進行處理
              bundles.AddCss("/main.css") // 告訴中間件需要將以下的文件最終打包成一個虛擬文件名
                  .Include("/Content/bootstrap.min.css")
                  .Include("/fonts/icomoon.min.css")
                  .Include("/Content/jquery.paging.css")
                  .Include("/Content/common/reset.css")
                  .Include("/Content/common/loading.css")
                  .Include("/Content/common/style.css")
                  .Include("/Content/common/articlestyle.css")
                  .Include("/Content/common/leaderboard.css")
                  .Include("/Content/microtip.min.css")
                  .Include("/Assets/breadcrumb/style.css")
                  .Include("/Assets/nav/css/style.css")
                  .Include("/Assets/tippy/tippy.css");
          
          
              bundles.AddJs("/main.js") // 告訴中間件需要將以下的文件最終打包成一個虛擬文件名
                    .Include("/Scripts/bootstrap.min.js")
                  .Include("/Scripts/bootstrap-suggest.min.js")
                  .Include("/Scripts/jquery.query.js")
                  .Include("/Scripts/jquery.paging.js")
                  .Include("/Scripts/ripplet.js")
                  .Include("/Scripts/global/scripts.js")
                  .Include("/Assets/tippy/tippy.js")
                  .Include("/Assets/newsbox/jquery.bootstrap.newsbox.js")
                  .Include("/Assets/tagcloud/js/tagcloud.js")
                  .Include("/Assets/scrolltop/js/scrolltop.js")
                  .Include("/Assets/nav/js/main.js");
          });
          
          


          最后,對于提升網站性能雖然非常重要,但合并文件如果太大,也是會影響性能的。另外采用合并中間件,對于開發的時候需要編寫額外的代碼、相對于原生的寫法比較不直觀,所以在優化性能的同時,我們也要找到一個平衡點,而不是一味的追求性能優化。


          源碼獲取

          私信回復:1070

          - End -

          推薦閱讀

          • 推薦一個簡單、靈活、好看、強大的 .Net 圖表庫


          React Router是React的事實上的標準路由庫。當您需要在具有多個視圖的React應用程序中導航時,將需要一個路由器來管理URL。React Router會做到這一點,使您的應用程序UI和URL保持同步。

          本教程向您介紹React Router v5以及您可以使用它進行的許多操作。

          介紹

          React是一個流行的庫,用于創建在客戶端呈現的單頁應用程序(SPA)。SPA可能具有多個視圖(又稱頁面),并且與傳統的多頁面應用程序不同,在這些視圖中導航不應導致整個頁面被重新加載。相反,我們希望視圖在當前頁面中內聯呈現。習慣了多頁應用程序的最終用戶希望SPA中具有以下功能:

          • 應用程序中的每個視圖都應具有唯一指定該視圖的URL。這樣一來,用戶便可以在URL上添加書簽以供以后參考。例如,www.example.com/products。
          • 瀏覽器的后退和前進按鈕應該可以正常工作。
          • 動態生成的嵌套視圖最好也應具有自己的URL。例如,,example.com/products/shoes/101其中101是產品ID。

          路由是保持瀏覽器URL與頁面上呈現的內容同步的過程。React Router使您可以聲明式處理路由。聲明式路由方法允許您通過說“路由應如下所示”來控制應用程序中的數據流:

          <Route path="/about" component={About} />
          

          您可以將<Route>組件放置在要渲染路線的任何位置。由于<Route>,<Link>以及我們將要處理的所有其他React Router API都是組件,因此您可以輕松地習慣于在React中進行路由。

          開始之前的注釋。人們普遍誤以為React Router是Facebook開發的官方路由解決方案。實際上,它是一個第三方庫,它以其設計和簡單性而廣受歡迎。如果您的需求僅限于用于導航的路由器,則可以從頭開始實施自定義路由器,而不會帶來太多麻煩。但是,了解React Router的基礎知識將使您更好地了解路由器應如何工作。

          總覽

          本教程分為不同的部分。首先,我們將使用npm設置React和React Router。然后,我們將直接進入React Router基礎知識。您將在實際中找到React Router的不同代碼演示。本教程介紹的示例包括:

          1. 基本導航路線
          2. 嵌套路由
          3. 帶路徑參數的嵌套路由
          4. 保護路由

          與構建這些路線有關的所有概念將一路討論。該項目的完整代碼可在此GitHub存儲庫中找到。進入特定的演示目錄后,運行npm install以安裝依賴項。要在開發服務器上為應用程序提供服務,請運行npm start并http://localhost:3000/轉至觀看演示示例。

          讓我們開始吧!

          設置React Router

          我假設您已經有一個開發環境正在運行。如果沒有,請轉到“ React和JSX入門 ”。另外,您可以使用Create React App生成創建基本React項目所需的文件。這是Create React App生成的默認目錄結構:

           react-router-demo
              ├── .gitignore
              ├── package.json
              ├── public
              │   ├── favicon.ico
              │   ├── index.html
              │   └── manifest.json
              ├── README.md
              ├── src
              │   ├── App.css
              │   ├── App.js
              │   ├── App.test.js
              │   ├── index.css
              │   ├── index.js
              │   ├── logo.svg
              │   └── registerServiceWorker.js
              └── yarn.lock
          

          該陣營路由器庫包括三個包:react-router,react-router-dom,和react-router-native。react-router是路由器的核心軟件包,而其他兩個是特定于環境的。react-router-dom如果您正在構建網站,并且react-router-native正在使用React Native在移動應用程序開發環境中,則應使用。

          使用npm進行安裝react-router-dom:

          npm install --save react-router-dom
          

          React Router基礎

          這是我們路線的外觀示例:

          <Router>/* App component */
          class App extends React.Component {
            render() {
              return (
                <div>
                  <nav className="navbar navbar-light">
                    <ul className="nav navbar-nav">
                      /* Link components are used for linking to other views */
                      <li>
                        <Link to="/">Homes</Link>
                      </li>
                      <li>
                        <Link to="/category">Category</Link>
                      </li>
                      <li>
                        <Link to="/products">Products</Link>
                      </li>
                    </ul>
                  </nav>
                  /* Route components are rendered if the path prop matches the current URL*/
                  <Route path="/" component={Home} />
                  <Route path="/category" component={Category} />
                  <Route path="/products" component={Products} />
                </div>
              );
            }
          }
            <Route exact path="/" component={Home} />
            <Route path="/category" component={Category} />
            <Route path="/login" component={Login} />
            <Route path="/products" component={Products} />
          </Router>
          

          路由器

          您需要一個路由器組件和幾個路由組件來設置上述基本路由。由于我們正在構建基于瀏覽器的應用程序,因此可以使用React Router API中的兩種類型的路由器:


          1. <BrowserRouter>
          2. <HashRouter>

          它們之間的主要區別在于它們創建的URL:

          // <BrowserRouter>
          http://example.com/about
          
          // <HashRouter>
          http://example.com/#/about
          

          該<BrowserRouter>因為它使用了HTML5 API歷史來跟蹤你的路由器的歷史當中是兩個更受歡迎。的<HashRouter>,而另一方面,使用URL(的哈希部分window.location.hash)記住的東西。如果您打算支持舊版瀏覽器,則應堅持使用<HashRouter>。

          將<BrowserRouter>組件包裝在App組件周圍。

          index.js

          /* Import statements */
          import React from "react";
          import ReactDOM from "react-dom";
          
          /* App is the entry point to the React code.*/
          import App from "./App";
          
          /* import BrowserRouter from 'react-router-dom' */
          import { BrowserRouter } from "react-router-dom";
          
          ReactDOM.render(
            <BrowserRouter>
              <App />
            </BrowserRouter>,
            document.getElementById("root")
          );
          

          注意:路由器組件只能有一個子元素。子元素可以是HTML元素(例如div)或react組件。

          為了使React Router正常工作,您需要從react-router-dom庫中導入相關的API 。在這里,我已將導入BrowserRouter到中index.js。我還App從導入了組件App.js。App.js您可能已經猜到了,這是React組件的入口點。

          上面的代碼為我們整個App組件創建了一個歷史實例。讓我正式向您介紹歷史。

          歷史

          history是一個JavaScript庫,可讓您在運行JavaScript的任何地方輕松管理會話歷史記錄。history提供了一個最小的API,可讓您管理歷史記錄堆棧,導航,確認導航以及在會話之間保持狀態。— React Training文檔

          每個路由器組件都創建一個歷史對象,該對象跟蹤當前位置(history.location)以及堆棧中的先前位置。當前位置更改時,將重新渲染視圖,您會感到導航。當前位置如何變化?歷史對象具有諸如history.push()和的方法history.replace()。history.push()單擊<Link>組件history.replace()時調用,使用時調用<Redirect>。其他方法(例如history.goBack()和history.goForward())可用于通過后退或前進頁面來瀏覽歷史記錄堆棧。

          繼續,我們有鏈接和路線。

          鏈接和路線

          該<Route>組件是React路由器中最重要的組件。如果當前位置與路線的路徑匹配,它將呈現一些UI。理想情況下,<Route>組件應具有一個名為的prop path,并且如果路徑名與當前位置匹配,則它將被呈現。

          <Link>另一方面,該組件用于在頁面之間導航。與HTML錨點元素相當。但是,使用錨鏈接會導致瀏覽器刷新,這是我們不希望的。因此,我們可以使用<Link>導航到特定的URL,并在不刷新瀏覽器的情況下重新渲染視圖。

          我們已經介紹了創建基本路由器所需的所有知識。讓我們來建立一個。

          演示1:基本路由

          src / App.js

          /* Import statements */
          import React, { Component } from "react";
          import { Link, Route, Switch } from "react-router-dom";
          
          /* Home component */
          const Home = () => (
            <div>
              <h2>Home</h2>
            </div>
          );
          
          /* Category component */
          const Category = () => (
            <div>
              <h2>Category</h2>
            </div>
          );
          
          /* Products component */
          const Products = () => (
            <div>
              <h2>Products</h2>
            </div>
          );
          
          export default function App() {
            return (
              <div>
                <nav className="navbar navbar-light">
                  <ul className="nav navbar-nav">
                    <li>
                      <Link to="/">Homes</Link>
                    </li>
                    <li>
                      <Link to="/category">Category</Link>
                    </li>
                    <li>
                      <Link to="/products">Products</Link>
                    </li>
                  </ul>
                </nav>
                /* Route components are rendered if the path prop matches the current URL */
                <Route path="/" component={Home} />
                <Route path="/category" component={Category} />
                <Route path="/products" component={Products} />
              </div>
            );
          }
          

          我們已經在內部聲明了Home,Category和Products的組件App.js。盡管現在還可以,但是當組件開始變大時,最好為每個組件創建一個單獨的文件。根據經驗,如果組件占用的代碼超過10行,我通常會為其創建一個新文件。從第二個演示開始,我將為已變得太大而無法容納在文件中的組件創建一個單獨的App.js文件。


          在App組件內部,我們編寫了路由邏輯。所述<Route>的路徑與當前位置匹配,并且組件被渲染。應該渲染的組件作為第二個屬性傳入。

          這里/匹配/和/category。因此,兩條路線都匹配并渲染。我們如何避免這種情況?您應該使用以下命令將exact= {true}道具傳遞到路由器path='/':

          <Route exact={true} path="/" component={Home} />
          

          如果只在路徑完全相同時才希望顯示路線,則應使用精確的道具。

          嵌套路由

          要創建嵌套路線,我們需要更好地了解其<Route>工作原理。來做吧。

          <Route> 您可以使用三個道具來定義要渲染的內容:

          • 組件。我們已經看到了這一點。匹配URL時,路由器使用會從給定的組件中創建一個React元素React.createElement。
          • 渲染。這對于內聯渲染很方便。渲染道具需要一個函數,當位置與路線的路徑匹配時,該函數將返回一個元素。
          • 孩子們。children props與render類似,因為它需要一個返回React元素的函數。但是,無論路徑與位置是否匹配,都會渲染子級。

          路徑匹配

          路徑用于標識路由器應匹配的URL部分。它使用Path-to-RegExp庫將路徑字符串轉換為正則表達式。然后將其與當前位置進行匹配。

          如果路由器的路徑和位置成功匹配,則會創建一個對象,我們將其稱為匹配對象。匹配對象包含有關URL和路徑的更多信息。可通過以下屬性訪問此信息:

          • match.url。一個字符串,返回URL的匹配部分。這對于構建嵌套<Link>s 尤其有用
          • match.path。返回路由路徑字符串的字符串,即<Route path="">。我們將使用它來構建嵌套<Route>的。
          • match.isExact。如果匹配完全正確(沒有任何尾隨字符),則返回true的布爾值。
          • match.params。一個對象,其中包含由Path-to-RegExp包解析的URL中的鍵/值對。

          既然我們已經了解了<Route>s,那么讓我們用嵌套路由構建一個路由器。

          開關組件

          在開始演示代碼之前,我想向您介紹該<Switch>組件。當多個<Route>一起使用時,所有匹配的路由都被包含在內。考慮一下演示1中的這段代碼。我添加了一條新路線來說明為什么<Switch>有用:

          <Route exact path="/" component={Home}/>
          <Route path="/products" component={Products}/>
          <Route path="/category" component={Category}/>
          <Route path="/:id" render = {()=> (<p> I want this text to show up for all routes other than '/', '/products' and '/category' </p>)}/>
          

          如果URL是/products,/products則呈現所有與該位置匹配的路由。因此,<Route>with路徑:id與Products組件一起呈現。這是設計使然。但是,如果這不是您所期望的行為,則應將<Switch>組件添加到路由中。使用<Switch>,只有<Route>與位置匹配的第一個孩子會被渲染。

          演示2:嵌套路由

          早前,我們創造了路線/,/category和/products。如果我們想要表單的URL /category/shoes怎么辦?

          src / App.js

          import React, { Component } from "react";
          import { Link, Route, Switch } from "react-router-dom";
          import Category from "./Category";
          
          export default function App() {
            return (
              <div>
                <nav className="navbar navbar-light">
                  <ul className="nav navbar-nav">
                    <li>
                      <Link to="/">Homes</Link>
                    </li>
                    <li>
                      <Link to="/category">Category</Link>
                    </li>
                    <li>
                      <Link to="/products">Products</Link>
                    </li>
                  </ul>
                </nav>
          
                <Switch>
                  <Route exact path="/" component={Home} />
                  <Route path="/category" component={Category} />
                  <Route path="/products" component={Products} />
                </Switch>
              </div>
            );
          }
          
          /* Code for Home and Products component omitted for brevity */
          

          與早期版本的React Router不同,在版本4及更高版本中,嵌套<Route>s應該最好放在父組件內部。也就是說,類別組件是此處的父組件,我們將聲明category/:name父組件內部的路由。

          src / Category.jsx

          import React from "react";
          import { Link, Route } from "react-router-dom";
          
          const Category = ({ match }) => {
            return (
              <div>
                {" "}
                <ul>
                  <li>
                    <Link to={`${match.url}/shoes`}>Shoes</Link>
                  </li>
                  <li>
                    <Link to={`${match.url}/boots`}>Boots</Link>
                  </li>
                  <li>
                    <Link to={`${match.url}/footwear`}>Footwear</Link>
                  </li>
                </ul>
                <Route
                  path={`${match.path}/:name`}
                  render={({ match }) => (
                    <div>
                      {" "}
                      <h3> {match.params.name} </h3>
                    </div>
                  )}
                />
              </div>
            );
          };
          export default Category;
          

          首先,我們為嵌套路線聲明了兩個鏈接。如前所述,match.url將用于構建嵌套鏈接和match.path嵌套路由。如果您在理解匹配的概念時遇到困難,請console.log(match)提供一些有用的信息,可能有助于澄清它。


          <Route
            path={`${match.path}/:name`}
            render={({ match }) => (
              <div>
                <h3> {match.params.name} </h3>
              </div>
            )}
          />
          

          這是我們首次嘗試動態路由。我們沒有在路徑中硬編碼,而是在路徑名中使用了變量。:name是一個路徑參數,捕獲所有內容,category/直到遇到另一個正斜杠為止。因此,像這樣的路徑products/running-shoes名將創建一個params對象,如下所示:

          {
            name: "running-shoes";
          }
          

          捕獲的數據應在道具傳遞方式下match.params或props.match.params取決于道具傳遞方式而可訪問。另一個有趣的事情是我們使用了render道具。render對于不需要自身組件的內聯函數,props非常方便。

          演示3:具有Path參數的嵌套路由

          讓事情變得更加復雜吧?現實世界中的路由器必須處理數據并動態顯示。假設我們具有以下形式的服務器API返回的產品數據。

          src / Products.jsx

          const productData = [
            {
              id: 1,
              name: "NIKE Liteforce Blue Sneakers",
              description:
                "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin molestie.",
              status: "Available",
            },
            {
              id: 2,
              name: "Stylised Flip Flops and Slippers",
              description:
                "Mauris finibus, massa eu tempor volutpat, magna dolor euismod dolor.",
              status: "Out of Stock",
            },
            {
              id: 3,
              name: "ADIDAS Adispree Running Shoes",
              description:
                "Maecenas condimentum porttitor auctor. Maecenas viverra fringilla felis, eu pretium.",
              status: "Available",
            },
            {
              id: 4,
              name: "ADIDAS Mid Sneakers",
              description:
                "Ut hendrerit venenatis lacus, vel lacinia ipsum fermentum vel. Cras.",
              status: "Out of Stock",
            },
          ];
          

          我們需要為以下路徑創建路由:

          • /products。這應該顯示產品列表。
          • /products/:productId。如果:productId存在的產品應顯示產品數據,如果不存在,則應顯示錯誤消息。

          src / Products.jsx

          /* Import statements have been left out for code brevity */
          
          const Products = ({ match }) => {
            const productsData = [
              {
                id: 1,
                name: "NIKE Liteforce Blue Sneakers",
                description:
                  "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin molestie.",
                status: "Available",
              },
          
              //Rest of the data has been left out for code brevity
            ];
            /* Create an array of `<li>` items for each product */
            const linkList = productsData.map((product) => {
              return (
                <li>
                  <Link to={`${match.url}/${product.id}`}>{product.name}</Link>
                </li>
              );
            });
          
            return (
              <div>
                <div>
                  <div>
                    <h3> Products</h3>
                    <ul> {linkList} </ul>
                  </div>
                </div>
          
                <Route
                  path={`${match.url}/:productId`}
                  render={(props) => <Product data={productsData} {...props} />}
                />
                <Route
                  exact
                  path={match.url}
                  render={() => <div>Please select a product.</div>}
                />
              </div>
            );
          };
          

          首先,我們<Links>使用productsData.ids 創建了s 的列表并將其存儲在中linkList。路由在路徑字符串中采用與產品ID對應的參數。

          <Route
            path={`${match.url}/:productId`}
            render={(props) => <Product data={productsData} {...props} />}
          />
          

          您可能期望component = { Product }使用內聯渲染功能。問題在于我們需要將productsData所有現有道具與產品組件一起傳遞。盡管還有其他方法可以執行此操作,但我發現此方法最簡單。{...props}使用ES6的傳播語法將整個props對象傳遞給組件。

          這是產品組件的代碼。

          src / Product.jsx

          /* Import statements have been left out for code brevity */
          
          const Product = ({ match, data }) => {
            var product = data.find(p => p.id == match.params.productId);
            var productData;
          
            if (product)
              productData = (
                <div>
                  <h3> {product.name} </h3>
                  <p>{product.description}</p>
                  <hr />
                  <h4>{product.status}</h4>{" "}
                </div>
              );
            else productData = <h2> Sorry. Product doesn't exist </h2>;
          
            return (
              <div>
                <div>{productData}</div>
              </div>
            );
          };
          

          該find方法用于在數組中搜索ID屬性等于的對象match.params.productId。如果產品存在,productData則顯示。如果不存在,則顯示“產品不存在”消息。

          保護路線

          對于最后的演示,我們將討論與保護路線有關的技術。因此,如果有人嘗試訪問/admin,則需要他們先登錄。但是,在保護路線之前,我們需要涵蓋一些內容。

          重新導向

          像服務器端重定向一樣,<Redirect>將歷史記錄堆棧中的當前位置替換為新位置。新位置由to道具指定。這是我們將如何使用<Redirect>:

          <Redirect to={{pathname: '/login', state: {from: props.location}}}
          

          因此,如果有人嘗試/admin在登出時訪問,他們將被重定向到該/login路由。有關當前位置的信息是通過狀態傳遞的,因此,如果身份驗證成功,則可以將用戶重定向回原始位置。在子組件內部,您可以在訪問此信息this.props.location.state。

          自定義路線

          定制路線是嵌套在組件內部的路線的俗稱。如果我們需要決定是否應繪制路線,則編寫自定義路線是可行的方法。這是在其他路線中聲明的自定義路線。

          src / App.js

          /* Add the PrivateRoute component to the existing Routes */
          <nav className="navbar navbar-light">
            <ul className="nav navbar-nav">
              ...
              <li><Link to="/admin">Admin area</Link></li>
            </ul>
          </nav>
          
          <Switch>
            <Route exact path="/" component={Home} data={data} />
            <Route path="/category" component={Category} />
            <Route path="/login" component={Login} />
            <PrivateRoute path="/admin" component={Admin} />
            <Route path="/products" component={Products} />
          </Switch>
          

          fakeAuth.isAuthenticated 如果用戶已登錄,則返回true,否則返回false。

          這是PrivateRoute的定義:

          src / App.js

          /* PrivateRoute component definition */
          const PrivateRoute = ({ component: Component, ...rest }) => {
            return (
              <Route
                {...rest}
                render={props =>
                  fakeAuth.isAuthenticated === true ? (
                    <Component {...props} />
                  ) : (
                    <Redirect
                      to={{ pathname: "/login", state: { from: props.location } }}
                    />
                  )
                }
              />
            );
          };
          

          如果用戶已登錄,則該路由將呈現Admin組件。否則,會將用戶重定向到/login。這種方法的好處是,它顯然更具生命性并且PrivateRoute可以重用。

          最后,這是Login組件的代碼:

          src / Login.jsx

          import React, { useState } from "react";
          import { Redirect } from "react-router-dom";
          
          export default function Login(props) {
            const { from } = props.location.state || { from: { pathname: "/" } };
            console.log(from);
            const [redirectToReferrer, setRedirectToReferrer] = useState(false);
          
            const login = () => {
              fakeAuth.authenticate(() => {
                setRedirectToReferrer(true);
              });
            };
          
            if (redirectToReferrer) {
              return <Redirect to={from} />;
            }
          
            return (
              <div>
                <p>You must log in to view the page at {from.pathname}</p>
                <button onClick={login}>Log in</button>
              </div>
            );
          }
          
          /* A fake authentication function */
          export const fakeAuth = {
            isAuthenticated: false,
            authenticate(cb) {
              this.isAuthenticated = true;
              setTimeout(cb, 100);
            }
          };
          

          下面的代碼行演示了對象分解,它是ES6規范的一部分:

          const { from } = this.props.location.state || { from: { pathname: "/" } };
          

          讓我們把拼圖拼在一起吧?這是我們使用React路由器構建的應用程序的最終演示。

          演示4:保護路線

          摘要

          如您在本文中所見,React Router是一個功能強大的庫,可補充React來構建更好的聲明式路由。與第5版中的React Router的早期版本不同,所有內容都只是“組件”。而且,新的設計模式非常適合React的做事方式。

          在本教程中,我們了解到:

          • 如何設置和安裝React Router
          • 路由的基礎知識,如一些必要的組件<Router>,<Route>并且<Link>
          • 如何為導航和嵌套路線創建最小的路由器
          • 如何使用路徑參數構建動態路由

          最后,我們學習了一些先進的路由技術,可以為受保護的路由創建最終的演示。

          推薦React 學習相關文章

          《前端必備的20種基本React工具「干貨」》


          主站蜘蛛池模板: 精品一区二区三区在线观看| 日本视频一区二区三区| 亚洲一区无码中文字幕乱码| 自慰无码一区二区三区| 精品福利一区二区三区精品国产第一国产综合精品 | 视频一区二区三区免费观看| 一区视频免费观看| 中文字幕色AV一区二区三区| 色婷婷综合久久久久中文一区二区 | 人妻无码视频一区二区三区| 久久精品一区二区国产| 麻豆果冻传媒2021精品传媒一区下载| 国产免费一区二区三区| 秋霞日韩一区二区三区在线观看| 相泽南亚洲一区二区在线播放| 国产一区二区三区在线| 精品无码一区二区三区电影| 国产成人无码aa精品一区| 久久久久人妻精品一区二区三区| 精品久久久中文字幕一区| 亚洲AV综合色区无码一区| 精品国产免费一区二区| 国产成人av一区二区三区在线 | 亚洲福利视频一区二区三区| 精品乱子伦一区二区三区高清免费播放| 极品人妻少妇一区二区三区| 亚洲第一区二区快射影院| 精品不卡一区二区| 亚洲一区二区免费视频| 亚洲爆乳无码一区二区三区| 一区二区三区亚洲视频| 国产乱子伦一区二区三区| 午夜福利一区二区三区高清视频| 成人免费av一区二区三区| 一区二区三区午夜| 成人毛片一区二区| 国产成人精品一区二三区在线观看| 狠狠色婷婷久久一区二区三区| 日韩人妻无码一区二区三区综合部| 日韩精品成人一区二区三区| 国产福利91精品一区二区|