使用Taro开发小程序的踩坑总结

·  阅读 4507

第一次使用Taro,把遇到的坑罗列一遍,给后继踩坑者做参考吧。

开发环境

  • taro版本:v1.3.0-beta.5
  • nodejs版本:v8.11.4

使用铁律

  • 静态资源404,
    检查静态资源引用是否使用ES6的import引入
    检查访问文件有没有使用下划线连接多个单词
  • 路径不对,找不到Js文件,
    删除dist文件夹,重新编译

踩过的坑

1. 实现小程序的slot的功能,开发工具翻译的wxml结果是slot内容和组件是同级,而非嵌套关系。《Children 与组合》Taro官方文档

这是小程序开发工具的bug, 最后视图窗口显示是正确的,实际是正确的github.com/NervJS/taro…

编译前组件代码

// component.js
<View className={'must-login-btn ' + className} hoverClass='btn-hover' onClick={this.onClick}>
{
  !userToken
  ? <Button className='user-info-btn' openType='getUserInfo' onGetuserinfo={handleGetUserInfo} />
  : ''
}
{ this.props.children }
</View>
复制代码
// page.js
<MustLoginBtn className='scan-btn' onClick={this.doScan}>
    <View className='scan-btn-inner'>
      <View className='scan-icon' />
      <Text className='btn-text'>扫小程序码</Text>
    </View>
</MustLoginBtn>
复制代码

开发工具中看到的wxml如下:

2. 使用externalClasses,为组件定义外部样式失效。《组件模板和样式》小程序官方文档,《组件的外部样式和全局样式》Taro官方文档

使用全局样式类,放弃使用externalClasses
在component文件内设置 addGlobalClass: true, 同时使用props获取外部定义的className
在page.js文件内使用自定义组件式时,设置className属性
在page.scss样式文件设置外部样式 在组件内调用组件的情况,外部样式也需要写在page的样式文件才有效(想哭)

/* CustomComp.js */
export default class CustomComp extends Component {
  // 设置全局样式
  static options = {
    addGlobalClass: true
  }
  // 使用prop设置自定义className
  static defaultProps = {
    className: ''
  }

  render () {
    return <View className={this.props.className}>这段文本的颜色不会由组件外的 class 决定</View>
  }
}
复制代码
/* MyPage.js */
import './MyPage.scss';
export default class MyPage extends Component {
  render () {
    return <CustomComp className="red-text" />
  }
}
复制代码
/* MyPage.scss */
.red-text {
  color: red;
}
复制代码

3. 在component文件内使用“函数式组件”出错了

函数的命名必须以 render 开头,render 后的第一个字母需要大写。《类函数组件》Taro官方文档

  • 错误表现:

这个不应该算是坑,是阅读文档不够深刻。

4. 编译后,静态资源图片总是404, 没有被复制到dist目录

taro中静态资源引入需要直接通过ES6的import语法引入《静态资源引用》Taro官方文档

以下引入方式被直接忽略资源引入:

<Image className='comp-checkbox__icon-inner' src='./assets/checked_icon.png' />
复制代码

5.‘生成类函数式组件的函数’内部再次调用‘生成类函数式组件的函数’出错了

官方给出的限制:
函数的命名必须以 render 开头,render 后的第一个字母需要大写
函数的参数不得传入 JSX 元素或 JSX 元素引用
函数不能递归地调用自身

虽然我没有哦调用自身,但是显然也是不能调用其他的‘生成类函数式组件的函数’
解决办法:
方法1:新建独立的组件文件ComponentA 和 ComponentB,然后在ComponentA中引入ComponentB,并render函数中使用
方法2:把jsx尽量写在一个类函数式组件内

错误的写法

class MainPage extends Component {
    renderB () {
        return <View>B</View>
    }
    renderA () {
        return (
            <View>
                {this.renderB()}
            </View>
        )
    }
    render () {
        ...
        return (
            ...
            {this.renderA()}
            ...
        )
    }
}

复制代码

TypeError: Property right of Ass ignnent Expression expected node to be of a type[ "Expression"] but  instead got null
复制代码

正确写法

class MainPage extends Component {
    renderA () {
        return (
            <View>
                {/* renderB 内容 start */}
                <View>B</View>
                {/* renderB 内容 end */}
            </View>
        )
    }
    render () {
        ...
        return (
            ...
            {this.renderA()}
            ...
        )
    }
}

复制代码

6. 父组件通过props传递函数给子组件,子组件触发函数后,this指向了子组件的props

被传递的函数,在jsx代码中做绑定

出现错误的代码:

// Parent
class Parent extends Component {
  constructor (props) {
    super(props)
    this.onTabClick.bind(this); // 绑定this
  }
  onTabClick () {
    console.log(this) // this指向child.props,而不是指向Parent的实例
  }
  render () {
    return <Child onClick={this.onTabClick}/>
  }
}

// Child
class Child extends Component {
  constructor (props) {
    super(props)
    this.handleClick.bind(this); // 绑定this指向
  }
  handleClick () {
    ...
    this.props.onClick();
  }
  render () {
    return (
        ...
        <View onClick={this.handleClick}></View>
        ...
    )
  }
}
复制代码

this指向正确的代码:

// 仅仅修改的父组件onTabClick.bind(this)的位置
// Parent
class Parent extends Component {
  constructor (props) {
    super(props)
    /*修改 start*/
    // this.onTabClick.bind(this); // 绑定this
    /*修改 end*/
  }
  onTabClick () {
    console.log(this) // this指向Parent的实例
  }
  render () {
    /*修改 start*/
    return <Child onClick={this.onTabClick.bind(this)}/>
    /*修改 end*/
  }
}
复制代码

原因:还没有找出来,正在学习中,请指教

7. 更新中……

分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改