这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战
TIP 👉 不畏浮云遮望眼,只缘身在最高层。——王安石《登飞来峰》
前言
Web Component是前端界一直非常热衷的一个领域,用第三方组件化的框架去实现的话,你需要依赖框架本身很多东西,很多时候我们只是简单的几个组件,不是很大,也不是很多,所以为了保证组件的`轻量,简单`,其实这个时候我们并不想采用第三方的框架。Dropdown 下拉菜单
import
import Dropdown from '@/components/Dropdown/Dropdown';
利用子组件如下:
const MenuItem = Dropdown.MenuItem;
const SubMenu = Dropdown.SubMenu;
Props
1. trigger
- 类型:string (必填)
- 默认值:click | hover
- 说明:下拉触发方式, click点击触发菜单,hover触发菜单
2. onClickMenu
- 类型:func
- 默认值:无
- 说明:点击触发回调函数更改子组件的classname,入参:
- {string} trigger 下拉触发方式
3. title
- 类型:string
- 默认值:无
- 说明:下拉按钮提示标题
MenuItem 子内容组件
import
import Dropdown from '@/components/Dropdown/Dropdown';
Props
1. trigger
- 类型:string (必填)
- 默认值:click | hover
- 说明:下拉触发方式, click点击触发菜单,hover触发菜单
2. className
- 类型:string (必填)
- 默认值:click | hover
- 说明:子内容外层div的class:'dropdownType-click' | 'dropdownType-hover'
3. disabled
- 类型:bool
- 默认值:false
- 说明:下拉的子内容某项置灰,true表示置灰,false表示正常
4. onClickMenuItem
- 类型:func (必填)
- 默认值:无
- 说明:点击某个单独的子内容执行动作,入参:
- {string | number} value | key 选中的某项子内容
SubMenu 子内容的父级
import
import Dropdown from '@/components/Dropdown/Dropdown';
Props
1. trigger
- 类型:string (必填)
- 默认值:click | hover
- 说明:下拉触发方式, click点击触发菜单,hover触发菜单
2. className
- 类型:string (必填)
- 默认值:click | hover
- 说明:子内容外层div的class:'dropdownType-click' | 'dropdownType-hover'
4. title
- 类型:string
- 默认值:无
- 说明:下拉按钮提示标题
让我们来实现dropdown.js
import React from 'react';
import PropTypes from 'prop-types';
import './dropdown.scss';
/**
* Dropdown 组件所传属性描述
* trigger 下拉触发方式 (string) click hover
* onClickMenu 点击更换classname (funtion)
* title 下拉菜单的名称 (string)
*/
class Dropdown extends React.Component {
// 入参类型检查
static propTypes = {
// 下拉触发方式 为其中一值即可
trigger: PropTypes.oneOf(['click', 'hover']),
// 点击下拉 更换classname改变样式的func.
onClickMenu: PropTypes.func,
// 下拉方式 值为鼠标右击
contextMenu: PropTypes.string,
// 下拉的按钮文字
title: PropTypes.string,
}
constructor(props) {
super(props);
this.checkboxWrapper = React.createRef();
this.state = {
trigger : props.trigger,
// clickX: null,
visible:false,//操控鼠标右击识别开关
flag:false,//操控鼠标点击识别开关
}
}
componentDidMount() {
document.addEventListener('click', this.hideAllMenu);
}
hideAllMenu = ()=>{
this.setState({flag : false });
}
showMenu(e){
let trigger = this.props.trigger;
e.nativeEvent.stopImmediatePropagation();
// e.stopPropagation();
console.log('>>>>', e)
this.setState({flag : !this.state.flag });
this.props.onClickMenu(this.state.trigger);//联动MenuItem的classname 必走 因classname要传值
}
render(){
return (
<div ref={this.checkboxWrapper} className={'dropdown-box '+this.props.trigger}
onClick={(e)=>{this.props.trigger == 'click' && this.showMenu(e)}}
>{this.state.flag}
<div className="drop-title">{this.props.title}
<i className="icon icon-shangjiantou mouseEnter" />
<i className="icon icon-xiajiantou mouseLeave" />
<i className={"icon " + (this.state.flag ? "icon-shangjiantou" : "icon-xiajiantou")} />
</div>
<div ref={'testDiv'} className="drop-cont">
{this.props.contextMenu ? (this.state.visible && this.props.children) : (
this.props.trigger == 'click' ? (this.state.flag && this.props.children) : this.props.children)}
</div>
</div>
)
}
}
/**
* MenuItem 组件所传属性描述
* trigger 下拉触发方式 (string) click hover
* className 联动点击更换classname (string)
* disabled 置灰状态 true:灰 false :正常
* onClickMenuItem 点击某个单独的项执行动作 (funtion)
*/
class MenuItem extends React.Component{
// 入参类型检查
static propTypes = {
//下拉触发方式 为其中一值即可
trigger: PropTypes.oneOf(['click', 'hover']),
//点击更换classname 必填
className: PropTypes.string.isRequired,
//下拉的某项置灰 true:灰 false :正常
disabled: PropTypes.bool,
//点击某个单独的项执行动作
onClickMenuItem: PropTypes.func,
}
constructor(props) {
super(props);
this.state = {
flag:true
};
}
menuAction(){
this.props.onClickMenuItem && this.props.onClickMenuItem();
}
render(){
return(
<div className={'menuItem dropdownType-' + (this.props.trigger == 'hover' ? this.props.trigger : this.props.className) +
' '+ (this.props.disabled ? 'disabled' : '')}
onClick={(e)=>{this.menuAction(e)}}>
{this.props.children}
</div>
)
}
}
/**
* SubMenu 组件所传属性描述
* title 有多级项的父级名称 (string)
* className 由父联动过来的点击更换classname (string)
* trigger 下拉触发方式 (string) click hover
*/
class SubMenu extends React.Component{
// 入参类型检查
static propTypes = {
//下拉触发方式 为其中一值即可
trigger: PropTypes.oneOf(['click', 'hover']),
//点击更换classname 必填
className: PropTypes.string.isRequired,
// 下拉的按钮文字
title: PropTypes.string,
}
constructor(props) {
super(props);
this.state = {
};
}
render(){
return(
<div className={'submenu dropdownType-' + (this.props.trigger == 'hover' ? this.props.trigger : this.props.className)}>
{this.props.title}
<i className="icon icon-youjiantou"></i>
<div className={'submenuItem-box'}>
{this.props.children}
</div>
</div>
)
}
}
Dropdown.MenuItem = MenuItem;
Dropdown.SubMenu = SubMenu;
export default Dropdown;
样式这边就不粘贴了
「欢迎在评论区讨论」