文档

比如 textArea 组件距离需要看两份文档。

  1. taro textArea
  2. 微信小程序文档 textArea

关于 textArea 的坑点

  1. 原生的组件永远的层级永远大于非原生组件的层级
  2. textArea 在 iphone 手机中存在内边距

目前一种方案是对 textArea 组件进行了相应封装, 展示的时候显示为自定义组件, 输入的时候使用原生 textArea.

basicTextArea.js

import Taro, { Component } from '@tarojs/taro'
import { Textarea, View } from '@tarojs/components'
import cx from 'classnames'
import './index.scss'
interface BasicTextAreaProps {
onChange: (...arg) => void
onFocus: (...arg) => void
onBlur: (...arg) => void
placeholder?: string
maxlength?: number
value: string
focus: boolean
}
const noop = () => {}
export default class BasicTextArea extends Component<BasicTextAreaProps, any> {
static defaultProps: BasicTextAreaProps = {
onChange: noop,
onFocus: noop,
onBlur: noop,
placeholder: '',
maxlength: -1,
value: '',
focus: false
}
handleInput = (...arg) => this.props.onChange(...arg)
handleFocus = (...arg) => this.props.onFocus(...arg)
handleBlur = (...arg) => this.props.onBlur(...arg)
render() {
const { platform } = Taro.getSystemInfoSync()
const { value, focus, placeholder, maxlength } = this.props
return (
<View
className={cx({
textarea_ios: platform === 'ios',
'textarea_android-placeholder': platform === 'android' && !value
})}
>
<Textarea
className={cx('textarea_text')}
value={value}
onInput={this.handleInput}
focus={focus}
onBlur={this.handleBlur}
placeholder={placeholder}
maxlength={maxlength}
/>
</View>
)
}
}

textArea.ts, 切换相应组件的代码主要在这里进行处理。

import Taro, { Component } from '@tarojs/taro'
import { View, Text, ScrollView } from '@tarojs/components'
import cx from 'classnames'
import BasicTextArea from './basicTextArea'
import './index.scss'
interface TextAreaProps {
placeholder?: string
maxlength?: number
onChange: (e: {detail: {value: string}}) => void
value: string
}
export default class TextArea extends Component<TextAreaProps, any> {
static defaultProps: Pick<TextAreaProps, 'placeholder' | 'maxlength'> = {
placeholder: '',
maxlength: -1,
}
state = {
isFocus: false,
}
handleChange(e) {
const { onChange } = this.props
onChange(e)
}
// 处理原生 textArea 失焦/聚焦
bindTextareaHandle(type: string) {
if (type == 'blur') {
this.setState({
isFocus: false,
})
} else if (type == 'focus') {
this.setState({
isFocus: true,
})
}
}
render() {
const { isFocus } = this.state
const { placeholder, maxlength, value } = this.props
const { platform } = Taro.getSystemInfoSync()
return (
<View>
{this.state.isFocus ?
<View className='textarea_content'>
<BasicTextArea
value={value}
onChange={this.handleChange.bind(this)}
focus={isFocus}
onBlur={this.bindTextareaHandle.bind(this, 'blur')}
maxlength={maxlength}
placeholder={placeholder}
/>
</View> :
<View
onClick={this.bindTextareaHandle.bind(this, 'focus')}
>
<ScrollView
scrollY={true}
className={'textarea_content'}
>
<Text className={cx('textarea_text', {
'textarea_text-placeholder': !value,
'textarea_text-ios': platform === 'ios',
})}>{value ? value : placeholder}</Text>
</ScrollView>
</View>
}
</View>
)
}
}

index.scss

.textarea_content {
width: 100%;
height: 192px;
padding-top: 24px;
padding-bottom: 24px;
font-size: 32px;
line-height: 48px;
border-radius: 16px;
background-color: #FFF;
-webkit-box-sizing: border-box;
box-sizing: border-box;
position: relative;
}
.textarea_text {
word-break: break-all;
width: 100%;
font-size: 32px;
line-height: 48px;
-webkit-appearance: none;
height: 144px;
overflow: scroll;
&-placeholder {
color: #999;
/* 模拟光标占位 */
padding-left: 2px;
}
&-ios {
/* 尽可能模拟原生 textArea 的字间距 */
letter-spacing: 0.1px;
}
}
/*微信原生 textarea placeholder 颜色, 误删 */
.textarea-placeholder {
color: #999;
font-size: 32px;
}
/* 修复 ios 下有 padding 的问题 */
.textarea_ios {
margin-top: -12px;
margin-left: -8px;
}
/* 安卓手机上的 placeholder 会偏上, 但是目前这解法会有一个影响用户的动画 */
.textarea_android-placeholder {
margin-top: 8px;
}