需求环境:
1. 一进入页面的时候,输入框聚焦, 手机键盘弹起
2. 输入框聚焦的时候,显示下面的列表(从:我是第1行开始)
3. 输入框文字数量大于0的时候,显示输入框右侧的 lime 色块
4. 点击 lime 色块,清空输入框的内容
5. 点击 red 色块,或者 手机键盘右下脚搜索,进行搜索(不显示下面的列表,显示其它的列表)
可能出现的问题:
1. 你点击 lime 色块,内容删除了,色块不显示了,但是手机键盘一直弹起
2. 点击 red 色块,或者 手机键盘右下脚搜索,手机键盘一直弹起
解决方案:不要使用类似于 vue 里面的 v-if,使用 v-show。即Taro 里面动态控制 style 里面的 display,来实现 显示与隐藏。
正常代码:
import { View, Text, Input } from '@tarojs/components'
import { useEffect, useRef, useState } from 'react'
import './index.scss'
export default function Index() {
const ref = useRef<HTMLInputElement>(null)
const [keyWord, setKeyWord] = useState('')
const [focusing, setFocusing] = useState(false)
const [list, setList] = useState([
{
line: 1,
txt: '我是第1行'
},
{
line: 2,
txt: '我是第2行'
},
{
line: 3,
txt: '我是第3行'
},
{
line: 4,
txt: '我是第4行'
},
{
line: 5,
txt: '我是第5行'
}
])
const addToList = () => {
setList(res => [
...res,
{
line: res.length + 1,
txt: keyWord
}
])
}
console.log(`%c渲染了`, 'display:block;padding: 5px 10px; background:#000;color:#ffa400')
return (
<View>
<View className='head'>
<View className='search' onClick={addToList}></View>
<Input
ref={ref}
value={keyWord}
focus
className='input'
placeholder='请输入测试内容'
confirmType='search'
alwaysEmbed
controlled
onInput={e => setKeyWord(e.detail.value)}
onFocus={() => {
setFocusing(true)
}}
onBlur={() => {
setFocusing(false)
}}
onConfirm={addToList}
/>
<View
className='del'
style={{
display: focusing && keyWord.length > 0 ? 'block' : 'none'
}}
onClick={() => {
if (keyWord.length > 0) {
setKeyWord('')
}
}}
></View>
</View>
<View
className='focus'
style={{
display: focusing ? 'block' : 'none'
}}
>
{list.map(item => {
return (
<View
className='row'
key={item.line}
onClick={() => {
setKeyWord(item.txt)
}}
>
{item.txt}
</View>
)
})}
</View>
</View>
)
}
样式:【scss】
.head {
display: flex;
$size: 80px;
.search {
width: $size;
height: $size;
background-color: red;
}
.input {
flex: 1;
height: $size;
box-sizing: border-box;
border-top: 1px solid purple;
border-bottom: 1px solid purple;
}
.del {
width: $size;
height: $size;
background-color: lime;
}
}
.focus {
$lineHeight: 80px;
.row {
height: $lineHeight;
line-height: $lineHeight;
border-bottom: 1px solid lime;
}
}
异常代码:【与正常代码的区别:不通过display来控制显示隐藏】
import { View, Text, Input } from '@tarojs/components'
import { useEffect, useRef, useState } from 'react'
import './index.scss'
export default function Index() {
const ref = useRef<HTMLInputElement>(null)
const [keyWord, setKeyWord] = useState('')
const [focusing, setFocusing] = useState(false)
const [list, setList] = useState([
{
line: 1,
txt: '我是第1行'
},
{
line: 2,
txt: '我是第2行'
},
{
line: 3,
txt: '我是第3行'
},
{
line: 4,
txt: '我是第4行'
},
{
line: 5,
txt: '我是第5行'
}
])
const addToList = () => {
setList(res => [
...res,
{
line: res.length + 1,
txt: keyWord
}
])
}
console.log(`%c渲染了`, 'display:block;padding: 5px 10px; background:#000;color:#ffa400')
return (
<View>
<View className='head'>
<View className='search' onClick={addToList}></View>
<Input
ref={ref}
value={keyWord}
focus
className='input'
placeholder='请输入测试内容'
confirmType='search'
alwaysEmbed
controlled
onInput={e => setKeyWord(e.detail.value)}
onFocus={() => {
setFocusing(true)
}}
onBlur={() => {
setFocusing(false)
}}
onConfirm={addToList}
/>
{focusing && keyWord.length > 0 && (
<View
className='del'
onClick={() => {
if (keyWord.length > 0) {
setKeyWord('')
}
}}
></View>
)}
</View>
{focusing && (
<View className='focus'>
{list.map(item => {
return (
<View
className='row'
key={item.line}
onClick={() => {
setKeyWord(item.txt)
}}
>
{item.txt}
</View>
)
})}
</View>
)}
</View>
)
}