Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Taro 小程序总结 #18

Open
sisterAn opened this issue Feb 16, 2019 · 0 comments
Open

Taro 小程序总结 #18

sisterAn opened this issue Feb 16, 2019 · 0 comments

Comments

@sisterAn
Copy link
Owner

最近,工作加班写小程序,虽然之前也写了不少小程序,但大多是使用小程序原生来写,也使用过wepy框架,风格和vue差不多,这次尝试使用taro框架。今天小程序告一断落,特此总结一波。

安装使用Taro

  1. 安装
npm install -g @tarojs/cli
  1. 使用命令创建模板项目
$ taro init myApp
  1. 微信小程序编译预览及打包
$ npm run dev:weapp
$ npm run build:weapp

主要详见官网Taro安装及使用,重要的事情说三遍,一定要认真看官方文档、官方文档、官方文档,做好基础的入门。

开发前注意

若使用 微信小程序预览模式 ,则需下载并使用微信开发者工具添加项目进行预览,此时需要注意微信开发者工具的项目设置

  • 需要设置关闭 ES6 转 ES5 功能,开启可能报错
  • 需要设置关闭上传代码时样式自动补全,开启可能报错
  • 需要设置关闭代码压缩上传,开启可能报错

框架

.
├── dist                   编译结果目录
├── config                 配置目录
|   ├── dev.js             开发时配置
|   ├── index.js           默认配置
|   └── prod.js            打包时配置
├── src                    源码目录
|   ├── pages              页面文件目录
|   |   ├── index          index 页面目录
|   |   |   ├── index.js   index 页面逻辑
|   |   |   └── index.css  index 页面样式
|   ├── app.css            项目总通用样式
|   └── actions            redux actions
|   └── constants         
|   └── libs             
|   └── net           
|   └── asset          
|   └── reducers       
|   └── store            
|   └── utils            
└── package.json

给组件设置 defaultProps

在微信小程序端的自定义组件中,只有在 properties 中指定的属性,才能从父组件传入并接收

Component({
  properties: {
    myProperty: { // 属性名
      type: String, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
      value: '', // 属性初始值(可选),如果未指定则会根据类型选择一个
      observer: function (newVal, oldVal, changedPath) {
         // 属性被改变时执行的函数(可选),也可以写成在 methods 段中定义的方法名字符串, 如:'_propertyChange'
         // 通常 newVal 就是新设置的数据, oldVal 是旧数据
      }
    },
    myProperty2: String // 简化的定义方式
  }
  ...
})

而在 Taro 中,对于在组件代码中使用到的来自 props 的属性,会在编译时被识别并加入到编译后的 properties 中,暂时支持到了以下写法

this.props.property

const { property } = this.props

const property = this.props.property

但是一千个人心中有一千个哈姆雷特,不同人的代码写法肯定也不尽相同,所以 Taro 的编译肯定不能覆盖到所有的写法,而同时可能会有某一属性没有使用而是直接传递给子组件的情况,这种情况是编译时无论如何也处理不到的,这时候就需要大家在编码时给组件设置 defaultProps 来解决了。

export default class LGLine extends Component {
  static propTypes = {
    value: string,
  };

  static defaultProps = {
    value: '',
  };
  render () {
    const { value } = this.props
    return (
      <View className='height-1 base-width-12'>
      </View>
    )
  }

}

组件设置的 defaultProps 会在运行时用来弥补编译时处理不到的情况,里面所有的属性都会被设置到 properties 中初始化组件,正确设置 defaultProps 可以避免很多异常的情况的出现。

JS 编码必须用单引号

在 Taro 中,JS 代码里必须书写单引号,特别是 JSX 中,如果出现双引号,可能会导致编译错误。

环境变量 process.env 的使用

不要以解构的方式来获取通过 env 配置的 process.env 环境变量,请直接以完整书写的方式 process.env.NODE_ENV 来进行使用

// 错误写法,不支持
const { NODE_ENV = 'development' } = process.env
if (NODE_ENV === 'development') {
  ...
}

// 正确写法
if (process.env.NODE_ENV === 'development') {

}

cover-view

cover-view经常使用到换行,设置文本内容换行 white-space: normal;

动态获取view的滚动位置

由于我们在滚动页面中经常会使用到textareavideo等原生组件,这些原生组件在scroll-view中的支持并不友好,所有有时我们有时无法使用scroll-view,也就无法去获取scrollTop,例如Taro 拖拽排序,这时,可以这样做:

onPageScroll () {
    let that = this;
    var query = Taro.createSelectorQuery()
    query.select('.content-view').boundingClientRect()
    query.selectViewport().scrollOffset()
    query.exec(function(res) {
      that.setState({
        scrollPosition: {
          scrollTop: res[1].scrollTop,
          scrollY: that.state.scrollPosition.scrollY
        },
      })
    })
  }

性能提升

小程序项目中遇到的性能问题,大多是频繁地调用 setData 造成的,这是由于每调用一次 setData,小程序内部都会将该部分数据在逻辑层(运行环境 JSCore)进行类似序列化的操作,将数据转换成字符串形式传递给视图层(运行环境 WebView),视图层通过反序列化拿到数据后再进行页面渲染,这个过程下来有一定性能开销。

所以开发过程中,我们建议尽量对 setData 进行合并,减少调用次数,例如:

this.setData({ foo: 'Strawberry' })
this.setData({ foo: 'Strawberry', bar: 'Fields' })
this.setData({ baz: 'Forever' })

以上代码调用了 3 次 setData,造成不必要的性能开销,应对其进行合并:

this.setData({
    foo: 'Strawberry',
    bar: 'Fields',
    baz: 'Forever',
})

而使用 Taro 之后,更新数据时调用的 setState 为异步方法,它会自动地对同一事件循环里的多次 setState 调用进行合并处理,此外还会进行数据 diff 优化,自动剔除那些未变更的数据,从而有效避免了此类性能问题。例如:

// 初始时
this.state = {
    foo: '1967',
    bar: {
        foo: 'Strawberry',
        bar: 'Fields',
        baz: 'Forever',
    }
}
// 第一次更新
this.setState({
    bar: {
        foo: 'Norwegian',
        bar: 'Fields',
        baz: 'Forever',
    }
})
// 紧接着进行第二次更新
this.setState({
    foo: '1967',
    bar: {
        foo: 'Norwegian',
        bar: 'Wood',
        baz: 'Forever',
    }
})

以上代码虽然经过两次 setState,但只有 bar.foo 和 bar.bar 的数据更新了,此时 Taro 内部会自动对数据进行合并、并剔除重复数据,最终执行代码为:

// this.$scope 在小程序环境中为 page 实例
this.$scope.setData({
    'bar.foo': 'Norwegian',
    'bar.bar': 'Wood',
})

更多

其他的问题,请看下面:
Taro event handler 传递参数有问题
Taro 阻止事件冒泡
Taro 对接腾讯云对象存储服务COS

本文参考了Taro 在京东购物小程序上的实践最佳实践

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant