Better

Ethan的博客,欢迎访问交流

用 Taro + express + mongodb 做了个失败的玩具

由于是个失败的玩意,具体是啥就不想多说了,记录下一些使用过程中踩的一些坑吧,也算是攒点经验!

首先说说服务端

为了更快速的开发,服务端直接选用 Node 开发,使用 mongodb 数据库做存储。使用 MongoLass 作为 MongoDB 的驱动包

为什么选择 MongoLass,而不是更被人熟知的 Mongoose 呢,无非就是为了简单嘛

  • 提供可选的 Schema 机制,支持 required 和 default
  • 提供灵活的 plugin 机制,支持 global 级别和 model 级别,同时提供了许多常用的内置 plugins

首先碰到的第一个问题就是,根据 id 查找竟然找不到。这里有两种原因

  • 如果使用了 MongoLass Schema 的特性,那么 ObjectId 的字符串形式可以无缝使用
  • 但如果没使用 Schema 特性,则必须调用 Mongolass.ObjectID 手动生成一个 ObjectID 实例

我就是图省事,没有定义 Schema 特性,同时又不知道需要手动创建一个 ObjectID 实例,一直出现查找不到数据的问题

其实我没有使用 Schema 除了省事外,另一个原因就是不知道如何定义复杂结构的 Schema 类型,这里还是好好学习一下

首先了解下 MongoLass 支持的类型有

  • string
  • number
  • boolean
  • Mongolass.Types.ObjectId
  • Mongolass.Types.String
  • Mongolass.Types.Number
  • Mongolass.Types.Date
  • Mongolass.Types.Buffer
  • Mongolass.Types.Boolean
  • Mongolass.Types.Mixed

普通 number 和 Mongolass.Types.Number 的区别在于,后者会进行自动类型转换,无法转换在会进行报错提示

其实仔细需求,定义复杂结构的 Schema 本身就是伪需求,在关系型数据库中是完全不存在这种操作的。如果你的字段是一个复杂的结果,显然需要关联另一张表来实现。

再来说说 Taro

第一个问题,可能是 Taro 的 bug,使用 cnpm 安装 taro-ui,会不可用,必须使用 npm 安装才行。

函数式组件的 config 配置

新版本的 Taro 是支持 Hooks 新特性,但 Template 代码中却没有使用到 Hooks 作为演示,按照 Taro 的约定,在 Class 组件中使用 config 值可以用来指定一些针对该页面的配置,比如设置 navigationBarTitleText 标题。

难道对于页面组件,不能使用函数式组件吗,感觉不应该啊,这样应该会被吐槽死吧。于是尝试使用静态属性的方式,结果生效,我觉得这就很 nice,例子如下

function Home() { return <View>首页</View> }
Home.config = {
    avigationBarTitleText: "首页"
}

自定义组件

在编写 React 时,你可能会将一些比较小的组件直接书写在同一个文件中,也就是说一个文件中可能会声明多个组件,这在 Taro 中是不支持的,会导致该组件不被编译。

CSS 相关

组件样式说明

微信小程序的自定义组件样式默认是不能受外部样式影响的,例如在页面中引用了一个自定义组件,在页面样式中直接写自定义组件元素的样式是无法生效的。这一点,在 Taro 中也是一样,而这也是与大家认知的传统 Web 开发不太一样。

自定义组件样式

编写 React 组件时,通常我们都会支持 className 和 style props,供组件使用者来定义组件样式,但在 Taro 如果想传递样式给引用的自定义组件,直接传递 className 不可行。

需要利用 externalClasses 定义段定义若干个外部样式类,这里直接举例如下

function Container() {
    return <Child my-class="cssName" />
}

function Child() {
    return <View className="my-class">I am child</View>
}
Child.externalClasses = ['my-class']

externalClasses 需要使用 短横线命名法 (kebab-case),而不是 React 惯用的 驼峰命名法 (camelCase)。否则无效。

全局样式类

使用外部样式类可以让组件使用指定的组件外样式类,如果希望组件外样式类能够完全影响组件内部,可以将组件构造器中的 options.addGlobalClass 字段置为 true。

function Child() {
    return <View className="red-text">I am child</View>
}
Child.options = {
    addGlobalClass: true
}

关于 CSS Modules

Taro 中使用 CSS Modules 有两种模式,分别为全局转换及部分自定义转换模式,通过 namingPattern 配置进行控制

namingPattern 配置取值分别如下:

  • global,表示全局转换,所有样式文件都会经过 CSS Modules 转换处理,除了文件名中包含 .global. 的样式文件
  • module,表示自定义转换,只有文件名中包含 .module. 的样式文件会经过 CSS Modules 转换处理

自定义组件

无论是自定义组件还是使用 taro-ui 的组件,自定义组件的名称会表现为一个真实存在的节点,这对于编写 CSS 并不友好,会导致层级不对的问题。

App 设置

对于路由注册、window 设置以及权限等,位于 App.tsx 中,通过 config 属性指定



留言