在vue中根本就没有这个烦恼,因为vue已经帮我们封装好了。而react使用NavLink或者Link的时候默认是a标签,并没有给我们提供相应的tag方法,可有时候我们就是想要其他的标签怎么办,就需要我们自己手动来封装了,这也正是react的灵活之处。下面是我封装的代码。有不懂的或有更好的方法都可以给我留言。
// 实现Tag的封装
import styled from "styled-components";
import {NavLink,withRouter} from 'react-router-dom'
import React from 'react'
const OwnLinkItem = (props) => {
// 渲染成tag 实现vue中的tag功能
console.log(props.location.pathname,props.to,props.nav)
let Tag = props.tag || 'a'
// 需要添加的类名 也可以自己定义active类型 默认是active
let _class = props.className || ''
let _activeClassName = props.activeClassName || 'active'
// toObj 判断参数的类型 如果to是一个对象 需要取到props.to.pathname 否则建议是否以props.to开头
let isActive = props.toObj ? props.location.pathname === props.to.pathname: props.location.pathname.startsWith(props.to)
// props.nav 可以保证都能加到类名 避免isActive没匹配到时 丢失类名
let className = (props.nav && isActive )? _class + ' ' + _activeClassName : _class
return <Tag className = {className} onClick = {()=> props.history.push(props.to)}> {props.children} </Tag>
}
export const OwnNavLink = props => { // 加上自定义类名
let Item = withRouter(OwnLinkItem) // 用withRouter包上后就有了路由对象 history location match
return (
<Item {...props} nav/> // 返回的就是tag的类型
)
}
export const OwnActiveNavLink = styled(OwnNavLink)`
&.active{
color:pink;
}
&.ok{ // 给需要的link的标签自定义加上的类名 可以在这里配置样式
color:tomato
}
color:#333;
margin-left:10px;
font-size:15px;
`
样式使用的是styled-components,可以更彻底的实现react的组件化开发
// 引入上面封装的函数
import {OwnActiveNavLink} from './utils'
<OwnActiveNavLink tag = 'li' to = '/todoList'>TodoList</OwnActiveNavLink>
<OwnActiveNavLink activeClassName = 'ok' tag = 'li' second to'/user'>User</OwnActiveNavLink>