JavaScript >> Javascript 文檔 >  >> Tags >> URL

如何從 URL 路徑構建動態麵包屑

如何在 Joystick 組件中獲取 url.path 的值並將其轉換為動態麵包屑 UI。

開始

在本教程中,我們將使用 CheatCode 的全棧 JavaScript 框架 Joystick。 Joystick 將前端 UI 框架與用於構建應用的 Node.js 後端結合在一起。

首先,我們要通過 NPM 安裝 Joystick。確保在安裝之前使用 Node.js 16+ 以確保兼容性(如果您需要學習如何安裝 Node.js 或在計算機上運行多個版本,請先閱讀本教程):

終端

npm i -g @joystick.js/cli

這將在您的計算機上全局安裝操縱桿。安裝好之後,接下來我們新建一個項目:

終端

joystick create app

幾秒鐘後,您將看到一條消息已註銷到 cd 進入你的新項目並運行 joystick start

終端

cd app && joystick start

在此之後,您的應用應該可以運行了,我們可以開始了。

添加嵌套路由

為了演示麵包屑 UI,我們需要一組可以使用的嵌套路由。為簡單起見,讓我們先打開 index.server.js 在我們剛剛創建的項目的根目錄下添加文件並添加一些路由:

終端

import node from "@joystick.js/node";
import api from "./api";

node.app({
  api,
  routes: {
    "/": (req, res) => {
      res.render("ui/pages/index/index.js", {
        layout: "ui/layouts/app/index.js",
      });
    },
    "/nested": (req, res) => {
      res.render("ui/pages/index/index.js", {
        layout: "ui/layouts/app/index.js",
      });
    },
    "/nested/path": (req, res) => {
      res.render("ui/pages/index/index.js", {
        layout: "ui/layouts/app/index.js",
      });
    },
    "/nested/path/to": (req, res) => {
      res.render("ui/pages/index/index.js", {
        layout: "ui/layouts/app/index.js",
      });
    },
    "/nested/path/to/:thing": (req, res) => {
      res.render("ui/pages/index/index.js", {
        layout: "ui/layouts/app/index.js",
      });
    },
    "*": (req, res) => {
      res.render("ui/pages/error/index.js", {
        layout: "ui/layouts/app/index.js",
        props: {
          statusCode: 404,
        },
      });
    },
  },
});

在我們剛剛創建的應用程序中,index.server.js 文件是我們應用程序服務器的主要“起點”。在裡面,我們調用 node.app() @joystick.js/node 中的函數 包來啟動我們的服務器,將我們希望它加載的 API 和我們希望在我們的應用程序中可用的路由傳遞給它。

這裡我們要關注的是 routes ,特別是我們添加的所有以 /nested 開頭的路由 .在這裡,我們正在創建一個偽嵌套 URL 模式,我們可以使用它來測試我們的麵包屑生成代碼。

對於每個 /nested 路線,我們做同樣的事情:渲染 index 頁面組件(我們剛剛複制並粘貼了 / 的內容 每個 /nested 的路由回調函數 路線)。每個之間的區別是路徑本身。請注意,對於我們添加的每條路線,我們都會更深一層:

  • /nested
  • /nested/path
  • /nested/path/to
  • /nested/path/to/:thing

最終目標是通過這種結構,現在我們有一組嵌套的路線,我們可以輕鬆地將其表示為麵包屑。

接下來,我們要修改/ui/pages/index/index.js 我們在此處渲染的文件以構建我們的麵包屑 UI。

添加動態麵包屑生成器

當我們使用 joystick create app 創建我們的應用程序時 之前,我們還在 /ui/pages/index/index.js 處獲得了一個示例頁面組件 .現在,讓我們打開它並將現有內容替換為可用於構建麵包屑 UI 的骨架組件。

/ui/pages/index/index.js

import ui from '@joystick.js/ui';

const Index = ui.component({
  render: () => {
    return `
      <div>
      </div>
    `;
  },
});

export default Index;

有了這些,我們要做的第一件事就是連接麵包屑的實際創建,然後專注於將它們呈現到頁面上。為此,我們將依賴 methods Joystick 組件的屬性。

/ui/pages/index/index.js

import ui from '@joystick.js/ui';

const Index = ui.component({
  methods: {
    getBreadcrumbs: (component) => {
      // We'll build our breadcrumbs array here...
    },
  },
  render: () => {
    return `
      <div>
      </div>
    `;
  },
});

export default Index;

在 Joystick 組件中,methods 屬性包含與我們的組件相關的各種方法對象(JavaScript 中定義在對像上的函數的另一個名稱)。我們現在要做的是定義一個函數getBreadcrumbs() 這將執行繁重的工作,將我們的 URL 路徑轉換為一組對象,這些對象描述了我們要呈現的每個麵包屑。

/ui/pages/index/index.js

import ui from '@joystick.js/ui';

const Index = ui.component({
  methods: {
    getBreadcrumbs: (component) => {
      const pathParts = component?.url?.path?.split('/').filter((part) => part?.trim() !== '');
      return pathParts?.map((part, partIndex) => {
        const previousParts = pathParts.slice(0, partIndex);
        return {
          label: part,
          href: previousParts?.length > 0 ? `/${previousParts?.join('/')}/${part}` : `/${part}`,
        };
      }) || [];
    },
  },
  render: () => {
    return `
      <div>
      </div>
    `;
  },
});

export default Index;

為了清楚起見,我們已經在這裡轉儲了整個代碼,所以讓我們逐步完成它。首先,我們的目標是能夠調用這個函數getBreadcrumbs 並讓它返回一個對像數組給我們,其中每個對象描述我們的一個麵包屑。

要到達那裡,我們需要獲取用戶正在查看的當前路徑。在我們的應用程序中,我們有兩個選項,都同樣簡單。首先,在網絡瀏覽器中,我們總是可以通過 window.location.pathname 獲取當前路徑 全局值(location.pathname 簡稱)。因為我們在操縱桿應用程序中工作,所以在這裡,我們將使用 url.path 值(等同於 location.pathname ) 在我們的組件實例上可用。

您會注意到,在 Joystick 組件上定義方法時,如果在調用該函數時沒有向該函數傳遞任何參數,Joystick 會自動將最後一個可能的參數分配給組件實例。例如,如果我們調用 methods.getBreadcrumbs('something') ,上面的函數簽名將更改為 getBreadcrumbs: (someValue, component) => { ... } .

在我們的函數內部,來自 component 例如,我們使用 component.url.path 獲取當前路徑 作為一個字符串。為了得到一個數組,首先,我們需要將路徑分成幾部分。為此,我們需要使用 .split() 函數可用於 JavaScript 中的所有字符串。到 .split() , 我們可以傳遞一個我們想要在 at 分割的字符 .因為我們正在處理像 /nested/path/to/123 這樣的路徑 我們想在 / 處拆分 正斜杠字符。最終結果是這樣的數組:

['', 'nested', 'path', 'to', '123']

這讓我們大部分時間都得到了解決,但請注意這裡有一個空字符串。那是因為當我們做了一個 .split('/') ,第一個斜線被計算在內,但因為它前面沒有任何內容,所以我們只得到一個空值。

要處理這個問題,請注意這裡的整行是:

const pathParts = component?.url?.path?.split('/').filter((part) => part?.trim() !== '');

這說的是“採取 url.path 值作為字符串,使用 / 將其拆分為數組 正斜杠作為分隔符,然後,如果修剪其所有空格導致空字符串,則過濾掉結果數組中的任何部分。"

最終結果?我們得到一個像 ['nested', 'path', 'to', '123'] 這樣的干淨數組 在我們的 pathParts 變量。

有了這個數組,我們就有了構建麵包屑所需的東西。接下來,我們需要映射這個數組。對於每次迭代,我們都希望完成構建麵包屑對象所需的工作。每個麵包屑都有兩個屬性:label 這是用戶將在麵包屑鍊和 href 中看到的呈現名稱 這是麵包屑將鏈接到的 URL。

對於 label ,我們的工作很簡單:我們將重用路徑的名稱 part 我們目前正在循環。 href 有點棘手。在這裡,我們需要確保每個連續的麵包屑都知道它之前的內容,所以當我們點擊它時,我們會引用正確的 URL。

為此,我們在地圖內部添加了一個新變量 previousParts 這需要我們的 pathParts 數組並調用 .slice() 方法,說“給我從數組中的第一個元素到當前部分的索引的所有內容。”換句話說,這將為我們返回一個 new 包含當前 part 之前所有內容的數組 .

在我們從 .map() 返回的對像上 我們使用三元運算符來設置 href 的值 取決於 previousParts 的長度 大批。如果長度為0 ,我們正處於路徑的起點,因此沒有要渲染的先前部分。如果是這種情況,我們只返回 href 作為 /${part} .

如果有 previousParts ,我們使用 .join() 該數組上的方法將數組轉換回字符串,將結果字符串與當前 part 的名稱連接起來 .最終結果?對於每次迭代,我們都會得到這樣的結果:

{ label: 'nested', href: '/nested' }
{ label: 'path', href: '/nested/path' }
{ label: 'to', href: '/nested/path/to' }
{ label: '123', href: '/nested/path/to/123' }

這就是得到 我們的麵包屑。現在,讓我們將它們渲染到頁面上。

/ui/pages/index/index.js

import ui from '@joystick.js/ui';

const Index = ui.component({
  methods: {
    getBreadcrumbs: (component) => { ... },
  },
  css: `
    .breadcrumbs {
      display: flex;
    }

    .breadcrumbs li {
      list-style: none;
    }

    .breadcrumbs li:before {
      content: "/";
      display: inline-flex;
      margin-right: 10px;
    }

    .breadcrumbs li:not(:last-child) {
      margin-right: 10px;
    }
  `,
  render: ({ when, each, methods }) => {
    const breadcrumbs = methods.getBreadcrumbs();

    return `
      <div>
        ${when(breadcrumbs?.length > 0, `
          <ul class="breadcrumbs">
            ${each(breadcrumbs, (breadcrumb) => {
              return `
                <li><a href="${breadcrumb?.href}">${breadcrumb?.label}</a></li>
              `;
            })}
          </ul>
        `)}
      </div>
    `;
  },
});

export default Index;

我們要注意的部分在 render() 中 功能。在這裡,我們交換了空 <div></div> 的渲染 用我們的麵包屑。

致我們的render() 函數,我們預計 Joystick 將傳遞給我們一個表示當前組件實例的對象。而不是寫 render: (component) => {} 在這裡,我們使用 JavaScript 解構從該對像中“提取”我們想要的特定變量。所以,不要寫 component.when , component.each 等,我們可以直接寫when , each , 和 methods (使用簡寫指向相同的屬性)。

使用 methods 這個屬性,就在 render() 裡面 ,我們調用 methods.getBreadcrumbs() 將結果(我們的麵包屑對像數組)存儲在變量 breadcrumbs 中 .有了這個數組,接下來,我們使用 when() 操縱桿中的渲染函數,當我們傳遞給函數的第一個值是 true 時,它允許我們有條件地渲染一些 HTML .

在這裡,我們要返回一個呈現 <ul></ul> 的 HTML 字符串 (代表我們的麵包屑列表)。在那個 <ul></ul> 裡面 為了呈現每個麵包屑,我們使用 each() 渲染函數表示給定作為第一個參數傳遞的數組,對於該數組中的每個項目,調用作為第二個參數傳遞的函數。

對於該函數,我們希望接收傳遞給 each 的數組中的每一項 ,或者,我們的 breadcrumb 之一 對象。在函數內部,Joystick 希望我們為 breadcrumbs 的每次迭代返回一個 HTML 字符串 大批。因為我們在 <ul></ul> 裡面 標記,對於我們要呈現的每個麵包屑,<li></li> 帶有 <a></a> 的標籤 裡面的標籤。從那裡,我們只需使用普通的 JavaScript 插值來傳遞 href 的值 和 label 從當前的 breadcrumb 對象。

而已!在頂部,我們添加了一個 css 屬性與一些簡單的樣式來清理東西。如果我們打開瀏覽器並在嵌套路由之間切換,我們應該會看到麵包屑動態更新。

總結

在本教程中,我們學習瞭如何在 Joystick 應用程序中設置一些嵌套路由。然後,我們學習瞭如何創建一個採用當前路徑的操縱桿組件,並將其轉換為我們可以在 UI 中用於渲染的麵包屑對像數組。最後,我們學習瞭如何在 UI 中使用操縱桿的 when 有條件地渲染麵包屑 和 each 渲染函數。


Tutorial JavaScript 教程
  1. 帶有 ESBuild 的 React+Typescript 應用程序

  2. 使用 S3 和 Cloudfront 的邊緣服務

  3. 將您的 reactjs 站點轉換為響應本機應用程序

  4. 導演一部電影解釋節點包管理器(NPM)

  5. ESLint 對我來說似乎沒用。我應該使用它嗎?

  6. 如何使用 React 創建一個簡單的加載屏幕

  7. 從方向向量中獲取角度?

  1. 使用 React 進行運行時配置

  2. 電子冒險:第 76 集:NodeGui React 終端應用程序

  3. 設計和開發博客(作為開發人員) - 直播

  4. 使用 es5 將定義好的字符串格式化為對象

  5. 第 91 天:登陸頁面設計和實施。

  6. 當用戶允許或拒絕訪問物理位置時如何調用函數?

  7. jQuery 加載新窗口

  1. Strapi CMS 筆記

  2. 使用 Azure Functions 和 SignalR 製作奇怪的 GIF 牆

  3. Ideation 💡 - 從頭開始使用 React 構建井字遊戲

  4. 如何密碼保護任何網站?