使用 http 路径设置活动选项卡

Posted

技术标签:

【中文标题】使用 http 路径设置活动选项卡【英文标题】:Use http path to set active tab 【发布时间】:2021-11-15 10:26:43 【问题描述】:

我有这个垂直标签的例子:

import * as React from 'react';
import Tabs from '@mui/material/Tabs';
import Tab from '@mui/material/Tab';
import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';

interface TabPanelProps 
  children?: React.ReactNode;
  index: number;
  value: number;


function TabPanel(props: TabPanelProps) 
  const  children, value, index, ...other  = props;

  return (
    <div
      role="tabpanel"
      hidden=value !== index
      id=`vertical-tabpanel-$index`
      aria-labelledby=`vertical-tab-$index`
      ...other
    >
      value === index && (
        <Box sx= p: 3 >
          <Typography>children</Typography>
        </Box>
      )
    </div>
  );


function a11yProps(index: number) 
  return 
    id: `vertical-tab-$index`,
    'aria-controls': `vertical-tabpanel-$index`,
  ;


export default function VerticalTabs() 
  const [value, setValue] = React.useState(0);

  const handleChange = (event: React.SyntheticEvent, newValue: number) => 
    setValue(newValue);
  ;

  return (
    <Box
      sx= flexGrow: 1, bgcolor: 'background.paper', display: 'flex', height: 224 
    >
      <Tabs
        orientation="vertical"
        variant="scrollable"
        value=value
        onChange=handleChange
        aria-label="Vertical tabs example"
        sx= borderRight: 1, borderColor: 'divider' 
      >
        <Tab label="Item One" ...a11yProps(0) />
        <Tab label="Item Two" ...a11yProps(1) />
        <Tab label="Item Three" ...a11yProps(2) />
        <Tab label="Item Four" ...a11yProps(3) />
        <Tab label="Item Five" ...a11yProps(4) />
        <Tab label="Item Six" ...a11yProps(5) />
        <Tab label="Item Seven" ...a11yProps(6) />
      </Tabs>
      <TabPanel value=value index=0>
        Item One
      </TabPanel>
      <TabPanel value=value index=1>
        Item Two
      </TabPanel>
      <TabPanel value=value index=2>
        Item Three
      </TabPanel>
      <TabPanel value=value index=3>
        Item Four
      </TabPanel>
      <TabPanel value=value index=4>
        Item Five
      </TabPanel>
      <TabPanel value=value index=5>
        Item Six
      </TabPanel>
      <TabPanel value=value index=6>
        Item Seven
      </TabPanel>
    </Box>
  );

Sanbox:https://codesandbox.io/s/verticaltabs-material-demo-forked-cewtk?file=/demo.tsx

是否可以使用 url 链接来设置活动标签?例如:

http://localhost/tabs/one -> set tab 1 as active 
http://localhost/tabs/three -> set tab 3 as active 

我找到了这个示例https://reactrouter.com/web/example/nesting,但它看起来不适合我,因为我想继续使用 Tabs 组件。 Tabs 组件还有其他解决方案吗?

【问题讨论】:

您可以通过使用 react 路由器的历史记录和位置,将 react 路由器与 tabs 组件一起使用。 你能给我看一下代码示例吗? 使用 url 支持更新您的代码和框示例。谢谢 【参考方案1】:

我已更新您的沙盒示例。在这两个文件中都进行了更改。首先让我们讨论一下demo.tsx的变化

Demo.tsx

首先,我从react-router-dom 导入了几个钩子

import  useHistory, useLocation  from "react-router-dom";

添加了一个 util 函数,用于根据 url 路径获取活动选项卡。

function getNumber(location: string) 
  const pathname = location.split("/")[2];
  if (!pathname) return 0;
  else 
    switch (pathname) 
      case "two":
        return 1;
      case "three":
        return 2;
      case "four":
        return 3;

      default:
        return 0;
    
  

然后状态和挂钩初始化。初始状态还会检查 url 并根据组件挂载上的 url 参数激活相关选项卡。

const history = useHistory();
const location = useLocation();
const [value, setValue] = React.useState(getNumber(location?.pathname));

更改了基于索引更新选项卡的handleChange 函数。它现在不是更新选项卡的状态值,而是根据选项卡索引推送新的 url。

const handleChange = (event: React.SyntheticEvent, newValue: number) => 
history.push(
  `/$
    newValue === 1
      ? "tabs/two"
      : newValue === 2
      ? "tabs/three"
      : newValue === 3
      ? "tabs/four"
      : "tabs/one"
    `
  );
;

由于在上面的handleChange 函数中,value 没有被更新,这实际上是控制活动选项卡,我将该代码移动到 useEffect 挂钩,并依赖于 location 对象。每当位置更改时,这将自动更新相关选项卡。状态变化移动到useEffect来处理场景,当用户按下返回键回到上一个标签页时,我们可以根据location变化更新value状态。

React.useEffect(() => 
  setValue(getNumber(location?.pathname));
, [location]);

Index.tsx的变化

react-router-dom 导入一些组件来管理url导航。

import  BrowserRouter as Router, Switch, Route  from "react-router-dom";

比将整个应用程序代码移动到Router 中,这样,所有组件都可以访问路由器。

<Router>
  <StyledEngineProvider injectFirst>
    <Switch>
      <Route exact path="/tabs/:tab?" component=Demo />
      <Route exact path="/" component=Demo />
    </Switch>
  </StyledEngineProvider>
</Router>

这是更新后的codesandbox link。

【讨论】:

以上是关于使用 http 路径设置活动选项卡的主要内容,如果未能解决你的问题,请参考以下文章

在材料ui选项卡组件中将选项卡设置为活动

引导、导航选项卡、下拉菜单;如何根据 URI 设置活动选项卡

动态设置选项卡处于活动状态

Primefaces tabview:在选项卡更改时设置活动索引

在 API 设置上设置选项卡窗格处于活动状态?

在jquery中上传文件后设置当前选项卡处于活动状态