jimczj / jimczj.github.io

个人原创文章博客存放地址

Home Page:https://jimczj.github.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Taro 开发前注意事项

jimczj opened this issue · comments

成功安装 Taro 后,进行开发前,我们有必要了解一下 Taro 的一些注意事项避免踩坑。

微信小程序开发工具的配置

若使用微信小程序预览模式 ,则需下载并使用微信开发者工具(申请账号和开发者工具安装及建项目的方法可以参考前面《3.微信小程序开发入门与技术选型》的开发入门内容),添加项目进行预览,添加的路径为项目根目录下的 dist 文件夹。此外,由于 Taro 编译后的代码已经经过了转义和压缩,因此还需要注意微信开发者工具的项目设置

  • 设置关闭ES6转ES5功能
  • 设置关闭上传代码时样式自动补全
  • 设置关闭代码压缩上传

即在设置-项目设置里面,建议将设置配置如下:
image

Taro 与 React 的差异

由于微信小程序的限制,React 中某些写法和特性在 Taro 中还未能实现,后续将会逐渐完善。
截止到发稿前,Taro 的最新版本为1.0,因此以下讲解默认版本为1.0

暂不支持在 render() 之外的方法定义 JSX

由于微信小程序的 template 不能动态传值和传入函数,Taro 暂时也没办法支持在类方法中定义 JSX。

规则详情

以下代码会被 ESLint 提示警告,同时在 Taro(小程序端)也不会有效:

class App extends Component {
  _render() {
    return <View />
  }
}

class App extends Component {
  renderHeader(showHeader) {
    return showHeader && <Header />
  }
}

class App extends Component {
  renderHeader = (showHeader) => {
    return showHeader& & <Header />
  }
}

解决方案

render 方法中定义。

class App extends Component {

  render () {
    const { showHeader, showMain } = this.state
    const header = showHeader && <Header />
    const main = showMain && <Main />
    return (
      <View>
        {header}
        {main}
      </View>
    )
  }
}

不能在包含 JSX 元素的 map 循环中使用 if 表达式

规则详情

以下代码会被 ESLint 提示警告,同时在 Taro(小程序端)也不会有效:

numbers.map((number) => {
  let element = null
  const isOdd = number % 2
  if (isOdd) {
    element = <Custom />
  }
  return element
})

以下代码不会被警告,也应当在 Taro 任意端中能够运行:

numbers.map((number) => {
  let isOdd = false
  if (number % 2) {
    isOdd = true
  }
  return isOdd && <Custom />
})

解决方案

尽量在 map 循环中使用条件表达式或逻辑表达式。

numbers.map((number) => {
  const isOdd = number % 2
  return isOdd ? <Custom /> : null
})

numbers.map((number) => {
  const isOdd = number % 2
  return isOdd && <Custom />
})

不能使用 Array#map 之外的方法操作 JSX 数组

Taro 在小程序端实际上把 JSX 转换成了字符串模板,而一个原生 JSX 表达式实际上是一个 React/Nerv 元素(react-element)的构造器,因此在原生 JSX 中你可以随意地一组 React 元素进行操作。但在 Taro 中你只能使用 map 方法,Taro 转换成小程序中 wx:for

规则详情

以下代码会被 ESLint 提示警告,同时在 Taro(小程序端)也不会有效:

test.push(<View />)

numbers.forEach(numbers => {
  if (someCase) {
    a = <View />
  }
})

test.shift(<View />)

components.find(component => {
  return component === <View />
})

components.some(component => component.constructor.__proto__ === <View />.constructor)

以下代码不会被警告,也应当在 Taro 任意端中能够运行:

numbers.filter(Boolean).map((number) => {
  const element = <View />
  return <View />
})

解决方案

先处理好需要遍历的数组,然后再用处理好的数组调用 map 方法。

numbers.filter(isOdd).map((number) => <View />)

for (let index = 0; index < array.length; index++) {
  // do you thing with array
}

const element = array.map(item => {
  return <View />
})

不能在 JSX 参数中使用匿名函数

规则详情

以下代码会被 ESLint 提示警告,同时在 Taro(小程序端)也不会有效:

<View onClick={() => this.handleClick()} />

<View onClick={(e) => this.handleClick(e)} />

<View onClick={() => ({})} />

<View onClick={function () {}} />

<View onClick={function (e) {this.handleClick(e)}} />

以下代码不会被警告,也应当在 Taro 任意端中能够运行:

<View onClick={this.hanldeClick} />

<View onClick={this.props.hanldeClick} />

<View onClick={this.hanldeClick.bind(this)} />

<View onClick={this.props.hanldeClick.bind(this)} />

解决方案

使用 bind类参数绑定函数。

<View onClick={this.props.hanldeClick.bind(this)} />

不能在 JSX 参数中使用对象展开符

微信小程序组件要求每一个传入组件的参数都必须预先设定好,而对象展开符则是动态传入不固定数量的参数。所以 Taro 没有办法支持该功能。

规则详情

以下代码会被 ESLint 提示警告,同时在 Taro(小程序端)也不会有效:

<View {...this.props} />

<View {...props} />

<Custom {...props} />

以下代码不会被警告,也应当在 Taro 任意端中能够运行:

const { id, ...rest } = obj

const [ head, ...tail]  = array

const obj = { id, ...rest }

解决方案

开发者自行赋值

render () {
    const { id, title } = obj
    return <View id={id} title={title} />
}

不允许在 JSX 参数(props)中传入 JSX 元素

由于微信小程序内置的组件化的系统不能通过属性(props) 传函数,而 props 传递函数可以说 React 体系的根基之一,我们只能自己实现了一套组件化系统。而自制的组件化系统则不能使用内置组件化的 slot 功能。两权相害取其轻,我们暂时只能不支持该功能。

规则详情

以下代码会被 ESLint 提示警告,同时在 Taro(小程序端)也不会有效:

<Custom child={<View />} />

<Custom child={() => <View />} />

<Custom child={function () { <View /> }} />

<Custom child={ary.map(a => <View />)} />

解决方案

通过 props 传值在 JSX 模板中预先判定显示内容,或通过 props.children 来嵌套子组件

不支持无状态组件(stateless component)

由于微信的 template 能力有限,不支持动态传值和函数,Taro 暂时只支持一个文件只定义一个组件。为了避免开发者疑惑,暂时不支持定义 stateless component。

规则详情

以下代码会被 ESLint 提示警告,同时在 Taro(小程序端)也不会有效:

function Test () {
  return <View />
}

function Test (ary) {
  return ary.map(() => <View />)
}

const Test = () => {
  return <View />
}

const Test = function () {
  return <View />
}

以下代码不会被警告,也应当在 Taro 任意端中能够运行:

class App extends Component {
  render () {
    return (
      <View />
    )
  }
}

解决方案

使用 class 定义组件。

命名规范

Taro 函数命名使用驼峰命名法,如onClick,由于微信小程序的 wxml 不支持传递函数,函数名编译后会以字符串的形式绑定在 wxml 上,宥于 wxml 的限制,函数名有三项限制:

  • 方法名不能含有数字
  • 方法名不能以下划线开头或结尾
  • 方法名的长度不能大于20

请遵守以上规则,否则编译后的代码在微信小程序中会报以下错误。

image

推荐安装 eslint 编辑器插件

Taro 有些写法跟 React 有些差异,可以通过安装 ESLint 相关的编辑器插件来获得人性化的提示。由于不同编辑器安装的插件有所不同,具体安装方法请自行搜索,这里不再赘述。
如下图,就是安装插件后获得的提示。

image

image

其他

由于小程序不支持 svg 的限制,Taro 也不支持 svg。

总结

由于 JSX 中的写法千变万化,我们不能支持到所有的 JSX 写法,同时由于微信小程序端的限制,也有部分 JSX 的优秀用法暂时不能得到很好地支持。这些不支持的写法都可以通过其他写法来规避,同时 ESLint 相关插件都能很好地提醒用户避免踩坑。了解 Taro 这些注意事项后,接下来我们就来动手实现一个简单的 Todo 项目。