上节课我们介绍了如何添加新的todo
,而我们的功能实现的也挺多的了。但是离我们完整的需求还远得很呢,我们既然有了添加功能,那么自然要有删除功能。但是我们的需求中一直都是将删除按钮隐藏的。而且我们是要求鼠标移入时才显示,那么这节课我们来学习如何添加这个功能。
回顾
在开始这节课的内容之前我们先来对上节课的内容来做一个简单的回顾。
- 添加
todo
分为 5 步 - 输入
todo
- 按下回车键
- 获取到输入的值
- 添加到
App
组件的state
中 - 重新加载页面
- 通过
onKeyUp
来监听键盘事件 - 通过
keyCode
来判断是否是回车键 - 通过父组件传入子组件一个函数来提供一个修改父组件
state
的入口给子组件
以上便是上节课的主要知识点,接下来开始添加我们的新功能来实现鼠标移入效果
最终效果
我们来回想一下我需要什么效果?首先我们鼠标移动到每条todo
上面的时候要求todo
高亮,其实就只是修改一下背景色而已。其次,当我们鼠标移入的时候氩气在todo
右侧显示出删除按钮。
实现
既然我们已经知道了我们要的效果,那么我们来分析一下这么实现吧:
首先理性分析一下,有没有可能鼠标同时出现在两条todo
之上呢?是不是不可能的?而且我们如果在todo
列表中拖动鼠标,是不是要让我们鼠标触碰的todo
按顺序依次高亮,一旦鼠标离开马上就取消高亮?那么好,我们是不是将这些todo
都分别天剑鼠标移入事件和移出事件就好了?
那么我们分析一下怎么实现?既然我们要在每条todo
都加移入移出事件,那么是不是要在Item
组件上添加?因为我们在List
组件中是遍历了App
组件的state
然后嵌入了Item
组件,那么我们不可能说在遍历的时候添加啊,那只有在Item
组件中添加才最合理也最方便,那么我们来修改Item
组件:
export default class Item extends Component { render() { const {todo} = this.props; return ( <li onMouseEnter={this.handleMouse(true)} onMouseLeave={this.handleMouse(false)}> ... </li> ) } handleMouse = flag => { return () => { console.log(flag); }; }; }
我们来看这段代码,我们给<li>
加了两个事件,onMouseEnter
和onMouseLeave
。从名字上面可以看出就是鼠标进入事件和鼠标离开事件。而且我们给这两个事件绑定的都是handleMouse
方法。而且还穿了参数。通过true
和false
来让方法来判断是移入还是移出。
那么我们光这么写可以吗?我们是不是还要定义方法啊?那么好,来看handleMouse
方法。首先我们要接收传入的参数,但是还记不记得我们说过,事件绑定,都要保证绑定的是一个函数,那么也就意味着我们handleMouse
方法就要返回一个函数了。然后我们现在返回的函数中来打印一下我们传入的flag
看看效果,是不是和我们预期一样鼠标移入打印true
,移出打印false
。
正如我们预期的效果一样,既然我们已经完成了移入移出来触发效果,那么我们再来分析,鼠标移入,我们要使页面出现变化。可能有人要说了,不对啊,我们这数据也没变啊。样式变了,而且有新元素显示是不是也算是更新了页面呢?所以说,我们是不是可以把移入移出传入的flag
存放在state
中,然后在鼠标移动时修改state
来驱动页面更新?那么另外我们初始化的state
应该是什么样子呢?我们再来分析一下,初始状态和鼠标移出使得状态一致,那么初始化的state
是不是就应该和鼠标移出一致,直接使用false
。那么好,我们来修改一下Item
:
export default class Item extends Component { state = {mouse: false}; render() {...} handleMouse = flag => { return () => { this.setState({mouse: flag}); }; }; }
我们来看一下,我们设置了一个mouse
属性,初始化是false
。当我们鼠标移入时那么直接setState
把state
的值设为flag
就可以了。那么我们已经可以修改state
了,那么是不是可以通过state
来修改Item
的style
。
export default class Item extends Component { state = {mouse: false}; render() { const {todo} = this.props; const {mouse} = this.state; return ( <li style={{backgroundColor: mouse ? "#ddd" : "white"}} onMouseEnter={this.handleMouse(true)} onMouseLeave={this.handleMouse(false)}> ... </li> ) } handleMouse = flag => {...}; }
看一下,我们先是解构赋值,来从state
中拿到mouse
属性,然后在<li>
中添加style
属性。但是我们是不是不能把style
写死啊?而且我们是移入高亮移出就取消高亮,那么什么就用mouse
来做个判断就好了,所以我们来看一下效果:
现在我们实现了高亮了,但是删除按钮还没有显示。我们来看看我们预期的结果是高亮的同时显示删除按钮,那么是不是也可以通过mouse
来实现,但是怎么实现呢?我们来看为什么会隐藏?我们是不是给<button>
加了一个display
属性啊?但是现在我们加了鼠标移入移出事件,是不是就不能把display
像原来那样写死为none
了?那么我们是不是也用mouse
来判断一下就行了?好,我们来修改一下代码
export default class Item extends Component { state = { mouse: false }; render() { const { todo } = this.props; const { mouse } = this.state; return ( <li ...> ... <button className="btn btn-danger" style={{ display: mouse ? "block" : "none" }}>删除</button> </li> ) } handleMouse = flag => {...}; }
来看一下代码,我们用mouse
来判断,如果是true
,那么我们就显示,否则还是隐藏,现在再看一下结果:
这一次我们便可以使得鼠标移入则高亮且显示删除按钮。
总结
这节课没有什么特殊的知识点,都是过去的知识
- 事件绑定必须是函数
- 通过
state
驱动页面样式修改
Copyright statement:The articles of this site are all original if there is no special explanation, indicate the source please when you reprint.
Link of this article:https://work.lynchow.com/article/pointer_hover/