Nav 导航
如果项目中使用的是 0.x 版本的基础组件(@icedesign/base, @ali/ice, @alife/next),请在左侧导航顶部切换组件版本。
安装方法
- 在命令行中执行以下命令
npm install @alifd/next@latest -S
开发指南
何时使用
分为顶部导航和侧边导航,顶部导航提供全局性的类目和功能,侧边导航提供多级结构来收纳和排列网站架构。
注意事项
- iconOnly 只适用垂直方向。
API。
API
Nav
继承自
Menu
的能力请查看Menu
文档
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
children | 导航项和子导航 | ReactNode | - |
type | 导航类型可选值:'normal'(普通)'primary'(主要)'secondary'(次要)'line'(线形) | Enum | 'normal' |
direction | 导航布局可选值:'hoz'(水平)'ver'(垂直) | Enum | 'ver' |
hozAlign | 横向导航条 items 和 footer 的对齐方向,在 direction 设置为 'hoz' 并且 header 存在时生效可选值:'left', 'right' | Enum | 'left' |
activeDirection | 设置组件选中状态的 active 边方向可选值:null(无)'top'(上)'bottom'(下)'left'(左)'right'(右) | Enum | 当 direction 为 'hoz' 时,默认值为 'bottom',当 direction 为 'ver' 时,默认值为 'left' |
mode | 子导航打开的模式(水平导航只支持弹出)可选值:'inline', 'popup' | Enum | 'inline' |
triggerType | 子导航打开的触发方式可选值:'click', 'hover' | Enum | 'click' |
inlineIndent | 内联子导航缩进距离 | Number | 20 |
defaultOpenAll | 初始展开所有的子导航,只在 mode 设置为 'inline' 以及 openMode 设置为 'multiple' 下生效 | Boolean | false |
openMode | 内联子导航的展开模式,同时可以展开一个同级子导航还是多个同级子导航,该属性仅在 mode 为 inline 时生效可选值:'single', 'multiple' | Enum | 'multiple' |
selectedKeys | 当前选中导航项的 key 值 | String/Array | - |
defaultSelectedKeys | 初始选中导航项的 key 值 | String/Array | [] |
onSelect | 选中或取消选中导航项触发的回调函数签名:Function(selectedKeys: Array, item: Object, extra: Object) => void参数:selectedKeys: {Array} 选中的所有导航项的 keyitem: {Object} 选中或取消选中的导航项extra: {Object} 额外参数extra.select: {Boolean} 是否是选中extra.key: {Array} 导航项的 keyextra.label: {Object} 导航项的文本extra.keyPath: {Array} 导航项 key 的路径 | Function | - |
popupAlign | 弹出子导航的对齐方式(水平导航只支持 follow )可选值:'follow', 'outside' | Enum | 'follow' |
popupClassName | 弹出子导航的自定义类名 | String | - |
iconOnly | 是否只显示图标 | Boolean | - |
hasArrow | 是否显示右侧的箭头(仅在 iconOnly=true 时生效) | Boolean | true |
hasTooltip | 是否有 ToolTips (仅在 iconOnly=true 时生效) | Boolean | false |
header | 自定义导航头部 | ReactNode | - |
footer | 自定义导航尾部 | ReactNode | - |
embeddable | 是否开启嵌入式模式,一般用于Layout的布局中,开启后没有默认背景、外层border、box-shadow,可以配合<Nav style={{lineHeight: '100px'}}> 自定义高度 | Boolean | false |
Nav.Group
继承自
Menu.Group
的能力请查看Menu.Group
文档
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
label | 标签内容 | ReactNode | - |
children | 导航项和子导航 | ReactNode | - |
Nav.Item
继承自
Menu.Item
的能力请查看Menu.Item
文档
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
icon | 自定义图标,可以使用 Icon 的 type,也可以使用组件 <Icon type="icon type" /> | String/ReactNode | - |
children | 导航内容 | ReactNode | - |
Nav.PopupItem
继承自
Menu.PopupItem
的能力请查看Menu.PopupItem
文档
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
icon | 自定义图标,可以使用 Icon 的 type, 也可以使用组件 <Icon type="icon type" /> | String/ReactNode | - |
label | 标签内容 | ReactNode | - |
children | 弹出内容 | ReactNode | - |
Nav.SubNav
继承自
Menu.SubMenu
的能力请查看Menu.SubMenu
文档
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
icon | 自定义图标,可以使用 Icon 的 type,也可以使用组件 <Icon type="your type" /> | String/ReactNode | - |
label | 标签内容 | ReactNode | - |
selectable | 是否可选 | Boolean | false |
children | 导航项和子导航 | ReactNode | - |
ARIA and KeyBoard
按键 | 说明 |
---|---|
Up Arrow | 导航到上一项 |
Down Arrow | 导航到下一项 |
Right Arrow | 打开子菜单,导航到子菜单第一项;横向菜单条第一层,导航到右一项 |
Left Arrow | 关闭子菜单,导航到父级菜单;横向菜单条第一层,导航到左一项 |
Enter | 打开子菜单,导航到子菜单第一项 |
Esc | 关闭子菜单,导航到父级菜单 |
代码示例
最简单的使用方式。
查看源码在线预览
import { Nav } from '@alifd/next';
const { Item, SubNav } = Nav;
const header = <span className="fusion">FUSION</span>;
const footer = <a className="login-in" href="javascript:;">Login in</a>;
ReactDOM.render(
<Nav className="basic-nav" direction="hoz" type="primary" header={header} footer={footer} defaultSelectedKeys={['home']} triggerType="hover">
<Item key="home">Home</Item>
<SubNav label="Component" selectable>
<Item key="next">Next</Item>
<Item key="mext">Mext</Item>
</SubNav>
<Item key="document">Document</Item>
</Nav>
, mountNode);
.basic-nav .fusion {
margin: 8px 20px;
width: 100px;
color: #FFFFFF;
font-size: 20px;
}
.basic-nav .login-in {
margin: 0 20px;
color: #FFFFFF;
}
.basic-nav .next-nav-item {
width: 120px;
}
Nav 提供了丰富的配置,可以进行个性化定制。
查看源码在线预览
import { Nav, Radio } from '@alifd/next';
const { Item, SubNav } = Nav;
class App extends React.Component {
state = {
type: 'normal',
direction: 'hoz',
activeDirection: null,
triggerType: 'click'
}
setValue(name, value) {
this.setState({
[name]: value === '' ? null : value
});
}
setTriggerType(triggerType) {
this.setState({
triggerType
});
}
render() {
const { type, direction, activeDirection, triggerType } = this.state;
return (
<div>
<div className="demo-ctl">
<Radio.Group shape="button" size="medium" value={type} onChange={this.setValue.bind(this, 'type')}>
<Radio value="normal">type="normal"</Radio>
<Radio value="primary">type="primary"</Radio>
<Radio value="secondary">type="secondary"</Radio>
<Radio value="line">type="line"</Radio>
</Radio.Group>
<Radio.Group shape="button" size="medium" value={direction} onChange={this.setValue.bind(this, 'direction')}>
<Radio value="hoz">direction="hoz"</Radio>
<Radio value="ver">direction="ver"</Radio>
</Radio.Group>
<Radio.Group shape="button" size="medium" value={activeDirection === null ? '' : activeDirection} onChange={this.setValue.bind(this, 'activeDirection')}>
<Radio value="">activeDirection=null</Radio>
{direction === 'hoz' ? <Radio value="top">activeDirection="top"</Radio> : null}
{direction === 'hoz' ? <Radio value="bottom">activeDirection="bottom"</Radio> : null}
{direction === 'ver' ? <Radio value="left">activeDirection="left"</Radio> : null}
{direction === 'ver' ? <Radio value="right">activeDirection="right"</Radio> : null}
</Radio.Group>
<Radio.Group shape="button" size="medium" value={triggerType} onChange={this.setTriggerType.bind(this)}>
<Radio value="click">triggerType="click"</Radio>
<Radio value="hover">triggerType="hover"</Radio>
</Radio.Group>
</div>
<Nav className="custom-nav" type={type} direction={direction} activeDirection={activeDirection} triggerType={triggerType}>
<Item>Item 1</Item>
<Item>Item 2</Item>
<SubNav label="Sub Nav">
<Item>Item 3</Item>
<Item>Item 4</Item>
<SubNav label="Sub Nav">
<Item>Item 5</Item>
<Item>Item 6</Item>
</SubNav>
</SubNav>
<Item icon="account">
<a href="http://www.taobao.com" target="_blank">Taobao</a>
</Item>
</Nav>
</div>
);
}
}
ReactDOM.render(<App />, mountNode);
.demo-ctl {
background-color: #F1F1F1;
border-left: 4px solid #0D599A;
color: #0A7AC3;
margin-bottom: 20px;
padding: 5px;
}
.demo-ctl .next-radio-group {
display: block;
margin: 5px;
}
.custom-nav.next-hoz .next-nav-item {
width: 100px;
}
.custom-nav.next-ver {
width: 200px;
}
Nav 可设置 iconOnly 属性,只显示图标,以减少占用空间。
查看源码在线预览
import { Nav, Radio } from '@alifd/next';
const { Item, SubNav } = Nav;
class App extends React.Component {
state = {
iconOnly: false,
hasTooltip: true,
hasArrow: true
}
setValue(name, value) {
this.setState({
[name]: value === 'true'
});
}
render() {
const { iconOnly, hasTooltip, hasArrow } = this.state;
return (
<div>
<div className="demo-ctl">
<Radio.Group shape="button" size="medium" value={iconOnly ? 'true' : 'false'} onChange={this.setValue.bind(this, 'iconOnly')}>
<Radio value="true">iconOnly=true</Radio>
<Radio value="false">iconOnly=false</Radio>
</Radio.Group>
{iconOnly ?
<Radio.Group shape="button" size="medium" value={hasArrow ? 'true' : 'false'} onChange={this.setValue.bind(this, 'hasArrow')}>
<Radio value="true">hasArrow=true</Radio>
<Radio value="false">hasArrow=false</Radio>
</Radio.Group> : null}
{iconOnly ?
<Radio.Group shape="button" size="medium" value={hasTooltip ? 'true' : 'false'} onChange={this.setValue.bind(this, 'hasTooltip')}>
<Radio value="true">hasTooltip=true</Radio>
<Radio value="false">hasTooltip=false</Radio>
</Radio.Group> : null}
</div>
<Nav style={{ width: '200px' }} iconOnly={iconOnly} hasArrow={hasArrow} hasTooltip={hasTooltip}>
<Item icon="account">Navigation One</Item>
<Item icon="account">Navigation Two</Item>
<Item icon="account">Navigation Three</Item>
<Item icon="account">Navigation Four</Item>
<Item icon="account">Navigation Five</Item>
<SubNav icon="account" label="Sub Nav">
<Item icon="account">Item 1</Item>
<Item icon="account">Item 2</Item>
<Item icon="account">Item 3</Item>
<Item icon="account">Item 4</Item>
</SubNav>
</Nav>
</div>
);
}
}
ReactDOM.render(<App />, mountNode);
.demo-ctl {
background-color: #F1F1F1;
border-left: 4px solid #0D599A;
color: #0A7AC3;
margin-bottom: 20px;
padding: 5px;
}
.demo-ctl .next-radio-group {
margin: 5px;
}
建议只在垂直布局中使用。
查看源码在线预览
import { Nav } from '@alifd/next';
const { Item, Group } = Nav;
ReactDOM.render(
<Nav style={{ width: 240 }}>
<Group label="Group Label 1">
<Item icon="account">Navigation One</Item>
<Item icon="account">Navigation Two</Item>
<Item icon="account">Navigation Three</Item>
</Group>
<Group label="Group Label 2">
<Item icon="account">Navigation Four</Item>
<Item icon="account">Navigation Five</Item>
<Item icon="account">Navigation Six</Item>
</Group>
</Nav>, mountNode);
当 Nav 的 mode="inline" 时,openMode 可控制同级内联子导航的展开数量。
查看源码在线预览
import { Nav, Radio } from '@alifd/next';
const { Item, SubNav } = Nav;
class App extends React.Component {
state = {
openMode: 'single'
}
setValue(openMode) {
this.setState({
openMode
});
}
render() {
const { openMode } = this.state;
return (
<div>
<div className="demo-ctl">
<Radio.Group shape="button" size="medium" value={openMode} onChange={this.setValue.bind(this)}>
<Radio value="single">openMode="single"</Radio>
<Radio value="multiple">openMode="multiple"</Radio>
</Radio.Group>
</div>
<Nav style={{ width: 240 }} openMode={openMode}>
<SubNav label="Sub Nav 1">
<Item>Item 1</Item>
</SubNav>
<SubNav label="Sub Nav 2">
<Item>Item 1</Item>
<Item>Item 2</Item>
<SubNav label="Sub Nav 1">
<Item>Item 1</Item>
<Item>Item 2</Item>
</SubNav>
<SubNav label="Sub Nav 2">
<Item>Item 1</Item>
<Item>Item 2</Item>
</SubNav>
</SubNav>
<SubNav label="Sub Nav 3">
<Item>Item 1</Item>
<Item>Item 2</Item>
<Item>Item 3</Item>
<SubNav label="Sub Nav 1">
<Item>Item 1</Item>
<Item>Item 2</Item>
<Item>Item 3</Item>
</SubNav>
<SubNav label="Sub Nav 2">
<Item>Item 1</Item>
<Item>Item 2</Item>
<Item>Item 3</Item>
</SubNav>
<SubNav label="Sub Nav 3">
<Item>Item 1</Item>
<Item>Item 2</Item>
<Item>Item 3</Item>
</SubNav>
</SubNav>
<Item>Item</Item>
</Nav>
</div>);
}
}
ReactDOM.render(<App />, mountNode);
.demo-ctl {
background-color: #F1F1F1;
border-left: 4px solid #0D599A;
color: #0A7AC3;
margin-bottom: 20px;
padding: 5px;
}
.demo-ctl .next-radio-group {
margin: 5px;
}
当 Nav 的 mode="popup" 时,popAlign 可控制弹出子导航的对齐方式。
查看源码在线预览
import { Nav, Radio } from '@alifd/next';
const { Item, SubNav } = Nav;
class App extends React.Component {
state = {
popupAlign: 'follow'
}
setValue(popupAlign) {
this.setState({
popupAlign
});
}
render() {
const { popupAlign } = this.state;
return (
<div>
<div className="demo-ctl">
<Radio.Group shape="button" size="medium" value={popupAlign} onChange={this.setValue.bind(this)}>
<Radio value="follow">popupAlign="follow"</Radio>
<Radio value="outside">popupAlign="outside"</Radio>
</Radio.Group>
</div>
<Nav style={{ height: 400, width: 240 }} mode="popup" popupAlign={popupAlign} defaultOpenKeys={['sub-nav-2']}>
<SubNav key="sub-nav-1"label="Sub Nav 1">
<Item key="1">Item 1</Item>
</SubNav>
<SubNav key="sub-nav-2" label="Sub Nav 2">
<Item key="1">Item 1</Item>
<Item key="2">Item 2</Item>
</SubNav>
<SubNav key="sub-nav-3" label="Sub Nav 3">
<Item key="1">Item 1</Item>
<Item key="2">Item 2</Item>
<Item key="3">Item 3</Item>
</SubNav>
<SubNav key="sub-nav-4" label="Sub Nav 4">
<Item key="1">Item 1</Item>
<Item key="2">Item 2</Item>
<Item key="3">Item 3</Item>
<Item key="4">Item 4</Item>
</SubNav>
</Nav>
</div>
);
}
}
ReactDOM.render(<App />, mountNode);
.demo-ctl {
background-color: #F1F1F1;
border-left: 4px solid #0D599A;
color: #0A7AC3;
margin-bottom: 20px;
padding: 5px;
}
.demo-ctl .next-radio-group {
margin: 5px;
}