左侧sidebar和整体分开滚动,可在X轴正常显示二级菜单

今天给大家带来react+antd项目实战:

项目需求:

  1. 左侧sidebar与整体分开滚动
  2. 左侧sidebar的二级菜单是在sidebar的右侧显示
  3. 严格要求二级菜单距离一次菜单的距离
  4. 左侧sidebar可收起展开
  5. sidebar收起展开的时候有0.3秒的动漫效果
  6. 二级菜单的箭头始终指着一级菜单

左侧sidebar和整体分开滚动,可在X轴正常显示二级菜单

我们看到这个需求脑子里面就会去想用什么技术去解决它:

1. 左侧sidebar与主体分别有各自的滚动条的话就要给左侧的sidebar加overflow-x: hidden;

如果不想看到丑陋的滚动条的话就在加上&::-webkit-scrollbar { display: none;}
less语法如下:

.nav-content {
    width: 280px;
    background: #151524;
    height: 100vh;
    overflow-x: hidden;
    padding-bottom: 100px;
    &::-webkit-scrollbar {
      display: none;
    }
}

这样sidebar与主体就有各自的滚动效果了,我们再来看下一个需求

2. 左侧sidebar的二级菜单是在sidebar的右侧显示

这个其实是很难为情的,因为我们使用了overflow-x:hidden;才使得sidebar与主体有了不同的滚动条,这时候我们想让元素在sidebar的外面显示就有些困难了,在笔者的尝试下发现了,给二级菜单加position: absolute是肯定显示不出来的,只有给二级菜单加position: fixed;才会显示出来,可是这样的话我们就要去给一级菜单加入移入事件,然后去查看一级菜单在文档中的上边距和左边距,然后再根据取得到的值去设置二级菜单的位置。这样做不是不可以,可是这样性能会很差。
于是我们就要换个方法来实现,这时我们又发现了antd的Tooltip组件的内容可以是文字也可以是一个ReactNode。那么我们来尝试一下Tooltip会不会被隐藏掉:结果显示的是不会被隐藏掉,而且可以使用它的arrowPointAtCenter这个API去让Tooltip始终指向目标元素的中心。
第七个需求在这里一起解决了

//用Tooltip把你的一级菜单包上
<Tooltip
  placement="rightTop"
  title={tooltipContent}  //这个tooltipConent是你的二级菜单
  arrowPointAtCenter   //让二级菜单的箭头始终指向你的一级菜单中心
>
  <li key={item.path}>
  //这个li就是你的一次菜单
  </li>
</Tooltip>

3.严格要求二级菜单距离一次菜单的距离

我们现在使用的是Tooltip来包装的二级菜单,所以我们现在就要改变Tooltip距离一级菜单的距离
可是当我们使用TooltipoverlayStyle 这个API的时候发现改变left和top值无效,这时候为了检测究竟是什么问题我们就去控制台看了一下,发现我们更改的样式并没有应用上,这时候为了完成需求的我们并没有气馁,我们又尝试了给他加类名,然后用那个类名去控制Tooltip的left边距。结果发现left还是改不了,我们又加了一个!important才成功,这个大家要注意哈。距离一级菜单的距离就是看你的UI图,比如UI图上二级菜单距离一级菜单10px,那么你就设置Tooltip的左边距为一级菜单的宽度加上10px。
PS:注意这里要使用类名的方式控制Tooltip的样式,不要给Tooltip本身覆盖样式,否者会覆盖掉全局的其他的Tooltip样式。

4.一级菜单可伸缩
这个功能的话其实还是比较好实现的,就是记住你一级菜单收起和展开时候的宽度,然后写俩个样式,一个样式是设置为展开时候的左边距,一个样式是设置为收起时候的左边距。
然后在在你的react项目里面设置一个state状态,默认是展开的状态,然后当点击sidebar缩起的时候改变state的状态,然后根据state动态设置Tooltip的类名。这样就实现了一级菜单可伸缩,二级菜单始终距离一级菜单的距离都是指定距离了。
CSS代码如下:

body .expandTooltip {
  left: 178px!important;
}
body .packUpTooltip {
  left: 58px!important;
}

JS关键代码如下:

constructor() {
	super()
	this.state = {
		expand: true,
	}
}

onExpand = () => {
  //控制你sidebar伸缩展开的代码
  /。。。/
  // 这里的这个标记是用来改变你的收起展开状态的
  this.setState({
    expand: !this.state.expand,
  }
}

render() {
	return (
	/**其他内容代码*/
	<Tooltip
      placement="rightTop"
      title={tooltipContent}		//你的二级菜单
      overlayClassName={this.state.expand ? 'expandTooltip' : 'packUpTooltip'}	//你展开收起设置不同的类名
      arrowPointAtCenter   //让二级菜单的箭头始终指向你的一级菜单中心
    >
	//你的二级菜单
	</Tooltip>
	/**其他内容代码*/
	)
}

5.最后一个需求,收起展开的时候有0.3s的过渡效果
这就是控制你的sidebar的样式了,
在你sidebar的样式中添加如下代码:

transition: all ease 0.3s;		//所有的样式改变的时候都会有0.3s的过渡效果,如果只需要控制width就把all改成width即可
上一篇:java-Swing可以告诉我是否有活动的工具提示吗?


下一篇:echart tooltip实心小圆点