国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

react umi/max 頁(yè)簽(react-activation)

這篇具有很好參考價(jià)值的文章主要介紹了react umi/max 頁(yè)簽(react-activation)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

思路:通過(guò)react-activation實(shí)現(xiàn)頁(yè)面緩存,通過(guò)umi-plugin-keep-alive將react-activation注入umi框架,封裝頁(yè)簽組件最后通過(guò)路由的wrappers屬性引入頁(yè)面。

瀏覽本博客之前先看一下我的博客實(shí)現(xiàn)的功能是否滿足需求,實(shí)現(xiàn)功能:

- 頁(yè)面緩存
- 關(guān)閉當(dāng)前頁(yè)
- 阻止事件傳播
- 鼠標(biāo)右鍵>關(guān)閉當(dāng)前
- 鼠標(biāo)右鍵>關(guān)閉其他
- 鼠標(biāo)右鍵>關(guān)閉左側(cè)
- 鼠標(biāo)右鍵>關(guān)閉右側(cè)
- 鼠標(biāo)右鍵>全部關(guān)閉(默認(rèn)跳轉(zhuǎn)到首頁(yè))
- 鼠標(biāo)右鍵>重新加載(刷新緩存頁(yè)面)

1.下載依賴

pnpm install?react-activation@0.12.4

pnpm install?umi-plugin-keep-alive@0.0.1-beta.35

2.修改.umirc.ts文件配置

import { defineConfig } from '@umijs/max';

export default defineConfig({
  plugins: ['umi-plugin-keep-alive'],
  ...
});

3.封裝組件?

src目錄下創(chuàng)建layouts文件夾,創(chuàng)建BaseLayout.tsx文件和BaseTabs.tsx、index.less文件文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-804685.html

// BaseLayout.tsx

import { KeepAlive, Outlet, useRouteProps } from '@umijs/max';
import React from 'react';
import BaseTabs from './BaseTabs';

export default (): React.ReactElement => {
  const { originPath, name } = useRouteProps();

  return (
    <>
      <BaseTabs />
      <KeepAlive id={originPath} name={originPath} tabName={name}>
        <Outlet />
      </KeepAlive>
    </>
  );
};

// BaseTabs/index.tsx

import { history, useAliveController, useLocation } from '@umijs/max';
import { Dropdown, Tabs } from 'antd';
import React, { useState } from 'react';
import './index.less';

export default (): React.ReactElement => {
  const { pathname } = useLocation();

  // 獲取緩存列表
  const { getCachingNodes, dropScope, clear, refreshScope } =
    useAliveController();
  const cachingNodes = getCachingNodes();
  const [open, setOpen] = useState<{ path: string; open: boolean }>({
    path: '',
    open: false,
  });

  // 阻止右鍵事件冒泡
  const onRightClick = (
    e: React.MouseEvent<HTMLDivElement, MouseEvent>,
    name: string,
  ) => open.open && open.path === name && e.stopPropagation();

  // 點(diǎn)擊tab,跳轉(zhuǎn)頁(yè)面
  const clickTab = (path: string) => {
    history.push(path);
  };

  // 關(guān)閉tab,銷(xiāo)毀緩存
  const editTab = (path: any) => {
    dropScope(path);
    // 關(guān)閉當(dāng)前頁(yè)面,需跳轉(zhuǎn)到其他頁(yè)簽
    if (path === pathname) {
      const index = cachingNodes.findIndex((item) => item.name === path);
      if (index > 0) {
        history.push(cachingNodes[index - 1].name as string);
      } else {
        history.push(cachingNodes[1].name as string);
      }
    }
  };

  // 關(guān)閉當(dāng)前頁(yè)
  const onCurrent = (e: any) => {
    let targetKey = JSON.parse(e?.key).name;
    dropScope(targetKey);
    // 關(guān)閉當(dāng)前頁(yè)面,需跳轉(zhuǎn)到其他頁(yè)簽
    if (targetKey === pathname) {
      const index = cachingNodes.findIndex((item) => item.name === targetKey);
      if (index > 0) {
        history.push(cachingNodes[index - 1].name as string);
      } else {
        history.push(cachingNodes[1].name as string);
      }
    }
  };

  // 關(guān)閉其他
  const onOther = (e: any) => {
    let targetKey = JSON.parse(e?.key).name;
    history.push(targetKey);
    clear();
  };

  //關(guān)閉左側(cè)
  const onLeft = (e: any) => {
    let targetKey = JSON.parse(e?.key).name;
    const lastIndex = cachingNodes.findIndex((item) => item.name === pathname);
    const currIndex = cachingNodes.findIndex((item) => item.name === targetKey);
    if (currIndex > lastIndex) history.push(targetKey);
    cachingNodes.forEach((item, index) => {
      if (index < currIndex) {
        dropScope(item?.name || '');
      }
    });
  };

  // 關(guān)閉右側(cè)
  const onRight = (e: any) => {
    let targetKey = JSON.parse(e?.key).name;
    const lastIndex = cachingNodes.findIndex((item) => item.name === pathname);
    const currIndex = cachingNodes.findIndex((item) => item.name === targetKey);
    if (currIndex < lastIndex) history.push(targetKey);
    cachingNodes.forEach((item, index) => {
      if (index > currIndex) {
        dropScope(item?.name || '');
      }
    });
  };

  // 關(guān)閉全部
  const onAll = () => {
    history.push('/home');
    clear();
  };

  // 重新加載
  const onRefresh = (e: any) => {
    let targetKey = JSON.parse(e?.key).name;
    refreshScope(targetKey);
  };

  const labelDropdown = (name: string, label: string) => {
    const lastIndex = cachingNodes.findIndex((item) => item.name === name);
    return (
      <div onClick={(e) => onRightClick(e, name)}>
        <Dropdown
          trigger={['contextMenu']}
          onOpenChange={(e) => setOpen({ path: name, open: e })}
          menu={{
            items: [
              {
                label: '關(guān)閉當(dāng)前',
                key: JSON.stringify({ name, key: 'current' }),
                disabled: cachingNodes.length <= 1,
                onClick: onCurrent,
              },
              {
                label: '關(guān)閉其他',
                key: JSON.stringify({ name, key: 'other' }),
                disabled: cachingNodes.length <= 1,
                onClick: onOther,
              },
              {
                label: '關(guān)閉左側(cè)',
                key: JSON.stringify({ name, key: 'left' }),
                disabled: lastIndex === 0,
                onClick: onLeft,
              },
              {
                label: '關(guān)閉右側(cè)',
                key: JSON.stringify({ name, key: 'right' }),
                disabled: lastIndex === cachingNodes.length - 1,
                onClick: onRight,
              },
              {
                label: '全部關(guān)閉',
                key: JSON.stringify({ name, key: 'all' }),
                onClick: onAll,
                disabled: cachingNodes.length <= 1,
              },
              {
                label: '重新加載',
                key: JSON.stringify({ name, key: 'refresh' }),
                onClick: onRefresh,
              },
            ],
          }}
        >
          <div className={cachingNodes.length > 1 ? 'dropdown-label' : ''}>
            {label}
          </div>
        </Dropdown>
      </div>
    );
  };

  const tabItems = cachingNodes.map((item: any) => ({
    label: labelDropdown(item.name, item.tabName),
    key: item.name,
    closable: cachingNodes.length > 1,
  }));

  return (
    <Tabs
      hideAdd
      size='middle'
      type="editable-card"
      className="base-tabs"
      activeKey={pathname}
      onTabClick={clickTab}
      onEdit={editTab}
      items={tabItems}
    />
  );
};
// index.less

.base-tabs {
  .ant-dropdown-trigger {
    padding: 5px 10px;
    height: 100%;
  }
  .dropdown-label {
    padding: 5px 6px 5px 10px;
    height: 100%;
  }
  .ant-tabs-tab {
    padding: 0 !important;
  }
  .ant-tabs-tab-remove {
    margin-left: 0 !important;
    margin-right: 2px !important;
    padding-left: 0px !important;
  }
}

?4.修改路由

  routes: [
    {
      name: '首頁(yè)',
      path: '/home',
      component: './Home',
    },
    {
      name: '示例',
      path: '/example',
      routes: [
        {
          name: '權(quán)限演示',
          path: '/example/access',
          component: './Access',
          wrappers: ['@/layouts/BaseLayout'],
        },
        {
          name: ' CRUD 示例',
          path: '/example/table',
          component: './Table',
          wrappers: ['@/layouts/BaseLayout'],
        },
      ],
    },
  ],

5.效果

react umi/max 頁(yè)簽(react-activation),第三方工具庫(kù),react.js,前端,前端框架

到了這里,關(guān)于react umi/max 頁(yè)簽(react-activation)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • umi/max如何給請(qǐng)求增加公共header

    umi/max如何給請(qǐng)求增加公共header

    直接上代碼 根據(jù) umi官網(wǎng) 介紹可知,umi/max僅提供一種運(yùn)行時(shí)配置的方法。 如果是搭配typescript開(kāi)發(fā)的話,最好使用@umi/max提供的RequestConfig類(lèi)型進(jìn)行字段控制。 因?yàn)槭窃赼pp.ts中添加的配置,但是并不知道該配置是在何時(shí)何地如何被使用的,所以去翻閱了一下umijs/plugin-request源碼

    2024年02月09日
    瀏覽(26)
  • React、Umi、RN 整體理解

    可以少去理解一些不必要的概念,而多去思考為什么會(huì)有這樣的東西,它解決了什么問(wèn)題,或者它的運(yùn)行機(jī)制是什么? React 是用于構(gòu)建用戶界面的 JavaScript 庫(kù) ,起源于 Facebook 的內(nèi)部項(xiàng)目,該公司對(duì)市場(chǎng)上所有 JavaScript MVC 框架都不滿意,決定自行開(kāi)發(fā)一套,用于架設(shè) Instagr

    2024年02月05日
    瀏覽(23)
  • react umi中使用svg線上圖片不加載問(wèn)題

    react umi中使用svg線上圖片不加載問(wèn)題

    參考鏈接: https://www.jianshu.com/p/c927122a6e82 前言: 在react項(xiàng)目中,我們本地通過(guò)img標(biāo)簽的src使用svg圖片是可以加載的,但是發(fā)布到線上圖片加載不出來(lái)。 解決方案 方案一 使用場(chǎng)景:直接在當(dāng)前頁(yè)面引入svg圖片 有一個(gè) svgr 插件,是支持以 react component 的方式,引入 svg 圖片的。

    2024年02月11日
    瀏覽(24)
  • 微前端使用qiankun實(shí)現(xiàn),react主應(yīng)用同時(shí)兼顧react,vue3,umi子應(yīng)用

    微前端使用qiankun實(shí)現(xiàn),react主應(yīng)用同時(shí)兼顧react,vue3,umi子應(yīng)用

    理解 :我們可以簡(jiǎn)單理解為微前端是將一個(gè)項(xiàng)目拆分成多個(gè)模塊,每個(gè)微前端模塊可以由不同的團(tuán)隊(duì)進(jìn)行管理,并可以自主選擇框架,并且有自己的倉(cāng)庫(kù),可以獨(dú)立部署上線 應(yīng)用場(chǎng)景 :1.當(dāng)公司代碼較老需要使用新的技術(shù)棧時(shí)我們可以使用微前端。2.多個(gè)團(tuán)隊(duì)同時(shí)開(kāi)發(fā)時(shí),每

    2024年02月09日
    瀏覽(21)
  • react--umi, 根據(jù)權(quán)限展示菜單,完成頁(yè)面權(quán)限分配,以及路由鑒權(quán)

    ? ? ? ?umi框架,prolayout布局,access設(shè)置菜單權(quán)限,initialState全局初始化數(shù)據(jù),配合使用,根據(jù)后端返回的權(quán)限信息,完成菜單的不同的權(quán)限的不同展示。 ? ? 1. umi 配合 patlayout 布局, 實(shí)現(xiàn)根據(jù)配置的路由展示菜單欄 ? ? 2. umi 的 access 插件,設(shè)置不同權(quán)限的菜單展示 ? ?

    2024年02月06日
    瀏覽(24)
  • springboot的 spring.redis.lettuce的max-active、max-idle、min-idle的搭配

    在Spring Boot中,使用Lettuce作為Redis客戶端是一種常見(jiàn)的選擇。Lettuce是一個(gè)高性能、可擴(kuò)展的異步Redis客戶端。下面是關(guān)于 application.yml 配置文件中 spring.redis.lettuce 的一些配置: 配置項(xiàng)的含義: spring.redis.host 和 spring.redis.port :配置Redis服務(wù)器的主機(jī)名和端口號(hào)。 spring.redis.dat

    2024年02月12日
    瀏覽(27)
  • Python第三方庫(kù)安裝教程、什么是第三方庫(kù)

    Python有一個(gè)全球社區(qū):https://pypi.org/,在這里我們可以搜索任何主題的Python第三方庫(kù)。PyPI全稱是Python Package Index,指的是Python包的索引,它由PSF(Python Software Foundation)來(lái)維護(hù),并且展示全球Python計(jì)算生態(tài)。 我們需要學(xué)會(huì)利用PyPI的主站檢索,找到我們使用和關(guān)心的Python第三方

    2024年02月03日
    瀏覽(94)
  • 引入第三方字體庫(kù) 第三方字體庫(kù)Google Fonts

    引入第三方字體庫(kù) 第三方字體庫(kù)Google Fonts

    googlefonts官方網(wǎng)站 googlefonts中國(guó)網(wǎng)站 本人是在微信小程序中引入 在static中建一個(gè)文件夾font-family 例如字體鏈接:https://fonts.font.im/css?family=Kirang+Haerang 將該鏈接的返回的資源的復(fù)制到css文件中 font-family.css main.js引入 微信小程序不校驗(yàn)合法域名就能看到結(jié)果

    2024年02月16日
    瀏覽(27)
  • Python第三方庫(kù)安裝——使用vscode、pycharm安裝Python第三方庫(kù)

    Python第三方庫(kù)安裝——使用vscode、pycharm安裝Python第三方庫(kù)

    在這里介紹vscode、Pycharm安裝python第三方庫(kù)的方法。 操作系統(tǒng):windows10 專業(yè)版 環(huán)境如下: Pycharm Comunity 2022.3 Visual Studio Code 2019 Python 3.8 pip:23.0.1 pycharm是一款很強(qiáng)大的、專用于寫(xiě)python的ide。 小白式安裝第三方庫(kù)往往能給初學(xué)者一種 “高級(jí)感” ,而對(duì)于使用慣了Linux的人而言

    2024年02月03日
    瀏覽(118)
  • Python第三方庫(kù)批量下載到本地,并離線批量安裝第三方庫(kù)

    Python第三方庫(kù)批量下載到本地,并離線批量安裝第三方庫(kù)

    鑒于公司內(nèi)網(wǎng)安裝的python版本為python3.6.5,而此時(shí)又需要安裝第三方庫(kù)pytest,本來(lái)是想直接在Python官網(wǎng)PyPI直接搜對(duì)應(yīng)可匹配跑python3.6.5版本的pytest進(jìn)行下載然后傳到內(nèi)網(wǎng)安裝即可,但是發(fā)現(xiàn)pytest依賴別的第三方庫(kù),根據(jù)報(bào)錯(cuò)裝了幾個(gè)依賴的第三方庫(kù)之后,發(fā)現(xiàn)還是一堆的問(wèn)題

    2024年02月07日
    瀏覽(104)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包