需求环境:

        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>
  )
}

Logo

智屏生态联盟致力于大屏生态发展,利用大屏快应用技术降低开发者开发、发布大屏应用门槛

更多推荐