组件属性

组件可以定义一些属性,用来接收组件使用者传入的值。组件的使用者可以在 WXML 节点中指定这些属性对应的值。

定义属性

使用 Definition 形式定义属性,写法如下:

export default Component({
  properties: {
    fooProp: {
      type: String,
      value: '',
    },
  },
})

使用 Chaining 形式定义属性,写法如下:

export default Component()
  .property('fooProp', {
    type: String,
    value: '',
  })
  .register()

上面的例子中定义了 fooProp 属性,定义时提供的 type 表示属性类型,value 表示初始值。

定义好属性之后,组件的使用者就可以在 WXML 节点中指定属性对应的值了,比如在页面中可以这样写:

<!-- page/index/index.wxml -->
<custom-component foo-prop="bar" />

在 WXML 中,驼峰写法的属性名可以换成连字符写法(当然也可以继续使用驼峰写法)。

给组件属性命名时,需要注意以下几点:

  • 属性名不能和 data 数据字段重名;
  • id class style slot 是 WXML 的保留属性,虽然可以设为组件属性,但无法在 WXML 中对它们赋值;
  • dataXxx 这样的属性名也无法在 WXML 中对它们赋值,因为 data-xxx="" 会被视为 dataset。

属性类型与简化定义

属性支持下表中列出的类型。

类型 默认值 说明
String '' 字符串
Number 数值
Boolean false 布尔值
Object null 对象
Array [] 数组
Function function () {} 函数
null null 表示属性支持任意类型

Function 类型仅 glass-easel 组件框架支持。在 exparser 组件框架中不能传递函数类型的属性,但可以将函数作为 Object 类型中的一个字段来传递。

如果一个属性的初始值 value 和它的类型默认值相同,就可以把属性定义简写为 type 本身,例如:

export default Component({
  properties: {
    fooProp: String,
  },
})
export default Component()
  .property('fooProp', String)
  .register()

初始值和默认值

初始值 指的是一个属性没有被指定值时所具有的值。

默认值 指的是一个属性没有被指定值时所具有的值,或者当属性被赋予非法值时,用来代替非法值的那个属性值。仅 glass-easel 组件框架支持。默认值需要使用一个函数来指定,写法如下:

export default Component({
  properties: {
    fooProp: {
      type: String,
      default: () => 'DEFAULT',
    },
  },
})
export default Component()
  .property('fooProp', {
    type: String,
    value: () => 'DEFAULT',
  })
  .register()

如果指定了默认值 default,就不能再指定初始值 value 了。

属性值类型转换

在 WXML 中为一个属性指定值时,会自动进行类型转换;如果转换失败,就会被视为非法值(这时会使用默认值来代替)。typenull 的属性不会进行类型转换。

举个例子,如果 custom-component 组件的 num-prop 属性是 Number 类型的,而在使用者的 WXML 中这样写:

<custom-component num-prop="1" />

这种情况下,num 属性会接收到数值 1

布尔类型属性值转换

对于 Boolean 类型的属性,如果在 WXML 中只写了属性名而没有指定值,会自动把它的值设为 true

<custom-component bool-prop />
<!-- 等价于 -->
<custom-component bool-prop="ANY" />
<!-- 等价于 -->
<custom-component bool-prop="{{true}}" />

如果想把它的值设为 false,就必须使用数据绑定写法,例如:

<custom-component bool-prop="{{false}}" />

对象、数组类型属性值转换

对象和数组类型的属性只能使用数据绑定写法,例如:

<custom-component array-prop="{{ [1, 2] }}" object-prop="{{ { a: 1, b: 2 } }}" />

在 glass-easel 组件框架中,绑定对象时外层的花括号可以省略:

<custom-component object-prop="{{ a: 1, b: 2 }}" />

可选类型

如果一个属性可能接受多种类型的值,可以用 optionalTypes 为它附加多个类型。例如:

export default Component({
  properties: {
    fooProp: {
      type: String,
      optionalTypes: [String, Boolean],
    },
  },
})
export default Component()
  .property('fooProp', {
    type: Number,
    optionalTypes: [String, Boolean],
  })
  .register()

使用 TypeScript 指定对象类型

使用 TypeScript 时,对于 typeArrayObject 的属性,会根据它初始值、默认值的类型作为这个属性字段的具体类型,来进行类型推断。

这时,可以通过 as 来指定具体类型:

export default Component()
  .property('objectProp', {
    type: Object,
    value: {} as {
      foo?: number
      bar?: string
    },
  })
  .register()

属性值变化监听器

属性值可以指定一个 observer,当属性值发生变化时,会调用这个函数。

export default Component()
  .property('foo', {
    type: String,
    observer(newVal, oldVal) {
      // 属性值变化后触发
    },
  })
  .register()

如果需要在 observer 中同步执行 setData 等更新操作,更推荐使用数据监听器,因为通常它有更好的性能。

对于 type 为 ObjectArray 的属性,如果通过该组件自身的 this.setData 来改变属性值的一个子字段,则依旧会触发属性 observer,且 observer 接收到的 newVal 是变化的那个子字段的值。

属性值比较器

仅 glass-easel 组件框架支持。

每当组件的使用者进行更新时,组件框架需要判断它使用的每个子组件是不是被更新了。框架的判断方法是,对比每个属性值,如果属性值不一样,就认为子组件被更新了。如果子组件被更新了,就会产生一定的更新开销。

对于子组件属性是数值、字符串、布尔值等基本类型时,框架可以直接对比它们的值。但对于对象、数组这样的值,框架难以比较,常常将它们直接视为被更新了。

这时可以通过 comparer 来指定一个属性值比较函数,避免不必要的更新、提升整体性能。如果 comparer 返回真,表示属性值变化了、组件需要更新。例如:

export default Component()
  .property('objectProp', {
    type: Object,
    comparer(newValue, oldValue) {
      return newValue.foo !== oldValue.foo || newValue.bar !== oldValue.bar
    },
  })
  .register()

页面根组件的属性值

对于页面根组件,属性值会从页面的 query 参数中获取(参数值会被自动 URL decode)。例如:

// pages/index/index.js
export default Component()
  .property('strProp', String)
  .property('numProp', Number)
  .register()

如果页面以 pages/index/index?strProp=foo&numProp=1 打开,那么 strProp 会被赋值 'foo'numProp 会被赋值 1

由于 query 参数是字符串,页面根组件的属性值应当是 StringNumber 类型的。

引用组件

一个由 JSON 配置、WXML 模板、WXSS 样式、JavaScript 脚本组成的自定义组件编写完成后,它就可以被其他组件引用了。

基本引用方式

在引用组件时,需要在 JSON 配置的 usingComponents 中指定引用的标签名和它对应的组件路径。下面用一个具体的例子来说明组件的引用方法。

首先,我们先编写一个自定义组件,位于 components/foo。首先编写 components/foo.json

{
  "component": true,
  "usingComponents": {}
}

然后编写 components/foo.wxml

<view class="foo">
  foo
</view>

编写 components/foo.wxss

.foo {
  color: blue;
}

最后编写 components/foo.js(以 Chaining 形式为例):

export default Component()
  .register()

这样,它就可以在其他自定义组件(包括页面)内使用。如果想在 pages/index/index 中引用它,那就在 pages/index/index.json 中这样写:

{
  "usingComponents": {
    "foo": "/components/foo"
  }
}

其中,"foo" 表示引用节点名,只能包含字母、数字、连字符和下划线,不能以数字开头。"/components/foo" 表示引用组件的路径,可以是相对路径或绝对路径。

然后,可以像使用内置组件那样,在 WXML 里面使用 <foo> 标签:

<foo />

slot 节点

在自定义组件中,可以使用一个特殊的标签 <slot />,用于接收外部传入的节点。

例如,在 components/foo.wxml 中:

<view class="foo">
  <slot />
</view>

pages/index/index.wxml 中,可以为 <foo> 添加子节点:

<foo>
  <view> bar </view>
</foo>

这样,在 <view class="foo"> 中的 <slot /> 就会被替换成 <view> bar </view>。通过这个特性就可以将两个组件 WXML 结构相互穿插到一起。

slot 节点还有几种不同的模式,请参考 slot 模式 。

组件脚本

组件脚本是页面的逻辑核心。它可以通过改变页面数据来最终决定界面上展示的内容。

组件脚本可以用 JavaScript 编写。不过,对于复杂的组件,更推荐使用 TypeScript 编写:api-typings 库中包含重要的类型定义,可以用于规范代码编写。

无论创建多少个实例,组件脚本文件本身只会被执行一次。

在组件脚本中,必须使用 Page 构造器或 Component 构造器来定义组件(而且只能定义一次)。通常有以下几种定义方式,可任选其一:

  • Page 构造器适合用来构造非常简单的页面;
  • Component 构造器的 Definition 形式适合用来构造简单的自定义组件(包括页面);
  • Component 构造器的 Chaining 形式适合用来构造逻辑复杂的自定义组件(包括页面)、适合使用 TypeScript 编写。

在使用构造器时,推荐将它 export default 出来(尽管这不是必需的)。

Page 构造器

对于简单的页面,可以使用 Page 构造器进行构造。它的结构更简洁,但不能使用某些复杂特性。

export default Page({
  data: {
    foo: 'bar',
  },
  onLoad() {
    // 页面创建时执行
  },
  onButtonTap() {
    // 用户事件触发时执行
  },
})

Page 构造器只能使用数据、简单生命周期和事件响应函数。如果需要使用其他组件框架特性,就必须使用 Component 构造器。

Component 构造器的 Definition 形式

Component 构造器有两种使用形式:Definition 形式和 Chaining 形式。它们是可以混用的,实现时可以根据习惯任选其一。

export default Component({
  data: {
    foo: 'bar',
  },
  lifetimes: {
    attached() {
      // 页面创建时执行
    },
  },
  methods: {
    onButtonTap() {
      // 用户事件触发时执行
    },
  },
})

如果想要将一个已经用 Page 构造的页面改用 Component 构造,只需要将简单生命周期和事件响应函数移入 methods 中。

Component 构造器的 Chaining 形式

Chaining 形式仅 glass-easel 原生支持。对于 exparser,需要使用 chaining-api-polyfill 。

对于新代码,更推荐使用 Chaining 形式编写。因为 Chaining 形式更适合组织复杂的组件逻辑,对 TypeScript 的支持也更好。

export default Component()
  .data(() => ({
    foo: 'bar',
  }))
  .init(function ({ data, setData, lifetime, method }) {
    // 组件实例初始化时执行一次

    // 上方定义的 `data` 可以直接作为局部变量使用(不需要写成 `this.data`)
    // `setData` 亦然(不需要写成 `this.setData`)

    lifetime('attached', () => {
      // 页面创建时执行
      data.foo === 'bar' // true
    })

    const buttonTap = method(() => {
      // 用户事件触发时执行
      setData({ foo: 'new bar' })
    })

    return {
      buttonTap,
    }
  })
  .register()

Chaining 形式的实例局部变量

Chaining 形式的 .init(...) 是一个实例初始化函数,它对于每个实例执行一次。

在这个函数里,可以自由定义局部变量。这些变量在实例之间是相互独立的。这也就是 Chaining 形式最大的优势。

// 在 JS 文件中的全局量是所有实例共享的
const sharedVar = 'shared'

export default Component()
  .init(function () {
    // 在 init 中的变量是每个实例专属的
    const instanceVar = 'instance'
  })
  .register()

Chaining 形式的逻辑拆分与形式混用

Chaining 形式中,链式方法可以多次调用。可以借此将复杂的组件逻辑自然拆分为几个部分。

export default Component()
  // 组件逻辑单元 A
  .data(() => ({
    appleCount: 0,
    applePrice: 1.2,
  }))
  .init(function ({ data, setData, method }) {
    const buyApple = method(() => {
      setData({ appleCount: data.appleCount + 1 })
    })
    return { buyApple }
  })

  // 组件逻辑单元 B
  .data(() => ({
    bananaCount: 0,
    bananaPrice: 3.4,
  }))
  .init(function ({ data, setData, method }) {
    const buyBanana = method(() => {
      setData({ bananaCount: data.bananaCount + 1 })
    })
    return { buyBanana }
  })
  .register()

也可以将 Definition 形式混入到 Chaining 形式中。

export default Component()
  // 组件逻辑单元 A(使用 Definition 形式)
  .definition({
    data: {
      appleCount: 0,
      applePrice: 1.2,
    },
    methods: {
      buyApple() {
        this.setData({
          data: this.data.appleCount + 1,
        })
      },
    },
  })

  // 组件逻辑单元 B
  .data(() => ({
    bananaCount: 0,
    bananaPrice: 3.4,
  }))
  .init(function ({ data, setData, method }) {
    const buyBanana = method(() => {
      setData({ bananaCount: data.bananaCount + 1 })
    })
    return { buyBanana }
  })
  .register()

组件框架

组件化

微信小程序的界面代码组织以 组件 作为基本单位。

一个页面可以由很多组件组合而成。这些组件分为两类:

  • 基础组件 是不可再分解的基础功能单元,如 <view> <image>
  • 可以用若干组件拼成一个大的组件,这样的组件称为 自定义组件 。

换句话说,页面由基础组件和自定义组件组合而成,而其中的自定义组件又由基础组件和其他自定义组件组合而成。特别地:

  • 页面实际上就是一个很大的自定义组件,也称为 页面根组件,所以页面具备所有自定义组件具有的特性;
  • 自定义组件可以递归地引用自身(但无限递归会导致栈溢出,请控制好递归条件)。

自定义组件相关特性自微信小程序基础库版本 1.6.3 开始支持。

组件代码构成

每个自定义组件的代码由四部分构成:

  • JSON 配置;
  • WXML 模板
  • WXSS 样式
  • JavaScript(或 TypeScript)脚本

这四个文件必须放在同一文件路径下、仅有文件扩展名不同。

其中,JSON 配置中需要至少包含 usingComponentscomponent 其中一项。

对于页面根组件,通常可以这样写:

{
  "usingComponents": {}
}

对于非页面根组件的自定义组件,通常可以这样写:

{
  "component": true,
  "usingComponents": {}
}

usingComponents 表示这个组件依赖的其他组件,可参考 组件引用 文档。从另一个角度说,一个组件的 JSON 配置、WXML 模板、WXSS 样式、JavaScript 脚本写完后,它就可以被其他组件引用了。

component 字段并不是必需的。它只会影响一些组件框架细节表现;即使未写明,只要有 usingComponents 字段,它依然可以作为组件使用。不过,仍然建议为所有非页面根的组件添加 component 字段,作为标识。

在开发者工具中预览效果

组件框架选择

目前,有两个组件框架可选。

exparser 是传统的组件框架,对旧代码具有最佳的兼容性。但由于历史原因,它缺少部分新特性、性能也不是最优。

glass-easel 是新一代的组件框架,由 更多特性更优性能 。如果想要深入了解它本身,可以参考 glass-easel 开源项目 。

在使用传统的 WebView 渲染引擎时,每个页面都可以选择使用其中一个组件框架来渲染。默认情况下,使用 exparser 作为组件框架,如果想改用 glass-easel,需要在页面 JSON 配置中声明:

{
  "usingComponents": {},
  "componentFramework": "glass-easel",
  "glassEaselWebview": true
}

关于上述配置的详细说明,请参考 迁移到 glass-easel 文档。

如果使用 Skyline 渲染引擎 ,就只能选用 glass-easel 作为组件框架。

其中的 componentFramework 字段可以放在 app.json 中使它全局生效。

页面中的自定义组件跟随其所在页面选用的组件框架。

尽管这两个组件框架有极高的相似性,它们之间仍有一些细微差异。可参考 迁移到 glass-easel 来进行组件框架升级。

页面间关系

微信小程序的界面可以由多个页面组成。

页面之间可以相互跳转,如打开一个新页面,关闭一个已有页面等。这些页面切换的时机称为 页面路由 。

页面路径参数

最基本地,一个页面可以用 router.navigateTo 打开一个新页面。打开新页面时,可以携带路径参数。参数采用 URL 编码形式。

// page/index/index.js
Page({
  viewTap: function() {
    var id = 'PRODUCT#1'
    this.router.navigateTo({
      // 传入路径参数时,使用 encodeURIComponent 是个好习惯
      url: '../product/product?id=' + encodeURIComponent(id),
    })
  },
})

在新打开的页面中,通过 this.options 可以获取到页面的路径参数。

// page/product/product.js
Page({
  onLoad: function() {
    // this.options 中的路径参数需要 decodeURIComponent
    var id = decodeURIComponent(this.options.id) // id === 'PRODUCT#1'
  }
})

目前更推荐使用 Component 构造器 来构造页面。这样使用时,可以将路径参数定义在 properties 中。

// page/product/product.js
Component({
  properties: {
    id: String,
  },
  lifetimes: {
    attached() {
      // this.data.id === 'PRODUCT#1'
    },
  },
})

路径参数的本质是页面的启动状态。在实践中,如果页面内容是由某些数据决定的,那这些数据应当是一个路径参数。例如:

  • 对于一个商品的详情页,页面所展示的商品由商品 ID 来决定,那么商品 ID 就应当是一个页面路径参数;
  • 对于一个学生的个人信息页,页面所展示的是哪个学生由学号来决定,那么学号就应当是一个页面路径参数。

使用路径参数可以在新页面启动时,向新页面传递数据。但如果两个页面之间需要持续进行双向的数据通信,或者有些数据不适合写在路径参数中,那就需要用到 EventChannel 页面间通信。

页面间通信

基础库 2.7.3 开始支持,低版本需做兼容处理。

如果一个页面由另一个页面通过 navigateTo 打开,这两个页面间将建立一条数据通道:

  • 被打开的页面可以通过 this.getOpenerEventChannel() 方法来获得一个 EventChannel 对象;
  • navigateTosuccess 回调中也包含一个 EventChannel 对象。

这两个 EventChannel 对象间可以使用 emiton 方法相互发送、监听事件。

在开发者工具中预览效果

界面渲染架构

微信小程序的界面由多个页面组成。在渲染每个页面时,微信小程序基础库内部的两个模块起着关键作用。

  • 组件框架 提供了 PagesetData 等重要的 JavaScript 接口,并结合 WXML 来构建界面结构。
  • 渲染引擎 将界面结构最终绘制成用户界面。

组件框架

组件框架为微信小程序提供了页面相关的 JavaScript 接口。与它相关的主要特性包括(但不限于):

  • 页面注册
  • 自定义组件
  • 事件系统
  • WXML

微信小程序基础库提供了两个可选的组件框架。选择不同的组件框架时,Page 等接口的具体实现、WXML 的运行方式都会有所不同。(每个页面可以独立选择使用哪个组件框架。)

  • exparser 是传统的组件框架(默认启用)。
  • glass-easel 是新一代组件框架,是一个开源项目,提供了更多特性、具有更好的性能表现。

详情请参考组件框架章节。

渲染引擎

渲染引擎为微信小程序提供了最终的界面绘制支持。与它相关的主要特性包括(但不限于):

  • 基础组件
  • WXSS 中的具体样式规则

微信小程序基础库提供了两个可选的渲染引擎。选择不同的渲染引擎时,可用的基础组件和 WXSS 样式规则会有一定区别。(每个页面可以独立选择使用哪个渲染引擎。)

  • Webview 是传统的渲染引擎(默认启用)。
  • Skyline 是更高效的渲染引擎,提供了很多增强特性、具有更好的性能表现。

渲染引擎对组件框架有一定的依赖。目前,如果选用了 Skyline 渲染引擎,就必须选用 glass-easel 组件框架。详情请参考 Skyline 渲染引擎章节。

程序

有一个特殊的 JS 文件 app.js

App()

整个微信小程序只有一个 App 实例,是全部页面共享的,更多的事件回调参考文档 注册程序 App 。

通过这个章节,你了解了微信小程序涉及到的文件类型以及对应的角色,在 下个章节 中,将介绍微信小程序协同工作与发布的相关内容。

国际化友好适配指南

随着外国用户来华数量日益增长,部分微信小程序存在手机号、证件、语言等限制,导致外国人用不了或用不好微信小程序。为改善外国用户体验,请开发者完成微信小程序国际化友好适配。

【优化项】

  1. 账号体系适配(必需):登录、购票链路兼容非 +86 国际手机号,放开国内 11 位手机号格式校验,或新增邮箱登录通道。
  2. 信息录入适配(必需):实名、购票信息录入支持护照等境外身份证件,放宽姓名字符输入校验限制。
  3. 多语言适配(重点):微信小程序已支持 18 种语言翻译,请关注翻译后页面及文本是否适配;为确保开发者微信小程序中的专有名词(如品牌名、产品词)翻译准确,请在微信小程序后台维护翻译词库。
  4. 双语物料:参照平台中英双语物料规范更新线下物料,优化外国用户扫码使用体验。

推荐使用国际化适配 Skill 快速定位代码优化项

  • 使用指引:微信小程序国际化适配 Skill
  • SkillHub:微信小程序国际化适配Skill — SkillHub
  • ClawHub:微信小程序国际化适配Skill — ClawHub

如有额外产品优化诉求或其他需求/反馈、技术问题可随时联系邮箱 miniprogram_global@tencent.com。

1. 账号体系适配(必需)

注册登录和购票页面兼容非 +86 国际手机号和放宽 11 位手机号校验规则、或支持邮箱登录、或接入微信小程序手机号快速验证组件;

1.1. 兼容非 +86 国际手机号

手机号是来华旅游场景下(如景区门票预订、餐厅点餐、酒店入住等)关键的履约信息。 建议开发者通过平台手机号快速验证组件或自行搭建手机号验证码通道形式收集用户手机号,以适配入境用户的使用习惯。

1.1.1. 国际手机号授权的接入方案

接入方式 接入方式说明
接入“手机号快速验证”组件(推荐) 微信平台已对非个人主体且完成认证的微信小程序开放手机号快速验证组件服务,旨在帮助开发者向用户发起手机号申请。
具体内容参照指引:手机号快速验证组件 | 微信开放文档
开发者自行搭建手机号验证码通道 开发者也可在微信小程序前端自行开发手机号填写及验证码发送的流程,以完成信息收集。
若涉及国际手机号的短信验证码下发,建议重点关注跨国发送的到达率。
  • 建议接入支持全球发送的国际短信服务商:保障验证码能穿透境外运营商网络。
  • 建议提供备选验证方案,例如:
    • 上行短信验证:允许用户主动发送特定代码到指定号码来完成验证。
    • 语音验证:通过电话语音播报的方式告知用户验证码。

无论是直接获取微信绑定的手机号还是用户手动填写,底层系统均需支持国际号码格式。

1.1.2. 国际手机号的兼容逻辑

兼容方式 说明
兼容国际区号 放宽对于手机号国际区号的限制,允许用户在前端选择非 +86 开头的手机号进行填写。
兼容国际号码位数 放宽对于“手机号必须为11位”的校验逻辑,避免境外手机号因长度问题被判定为错误手机号。

1.2 兼容邮箱登录验证

鉴于国际短信在跨国漫游场景下可能存在拦截或延迟,且海外用户具有高频使用电子邮箱的习惯,建议在手机号登录之外,增设“邮箱+验证码”或“邮箱+密码”的辅助验证/信息收集选项,确保在短信无法送达时,用户仍可通过邮箱完成身份验证并使用服务。

二、信息录入适配(必需)

实名认证和购票信息支持护照等境外证件、放宽姓名输入校验规则;

在实名认证、物流填写、票务预订等场景中,若表单字段限制过严(例如:仅限汉字、仅支持身份证等),将导致境外用户无法录入有效信息。开发者可从以下方向开展适配优化。

优化方向 说明
证件类型适配 在涉及实名制的业务场景中,在“居民身份证”之外,增设“护照”、“外国人永久居留身份证”等选项,并适配相应的证件号码校验规则。
姓名输入规则放宽
  • 取消“仅限汉字”的输入限制,允许输入英文字母及空格。
  • 增加字符长度上限:考虑到外籍人士姓名音译或原名较长,建议姓名字段长度限制放宽至50个字符以上,避免截断。

三、多语言适配(重点)

微信小程序已支持 18 种语言翻译,请关注翻译的页面及文本适配,避免译文溢出或显示不全;为确保开发者微信小程序中专有名词(如品牌名、产品词)翻译准确,请在微信小程序后台维护翻译词库;开发者也可自行适配多语言界面;

3.1 平台翻译能力适配

平台已为用户提供微信小程序翻译功能,支持18种语言。开发者可通过以下方式优化用户翻译功能在微信小程序的使用体验:

多语言适配方式 适配方式说明
页面适配(高优) 考虑多语言的文本长度、词汇分界等差异,开发者在微信小程序页面设计上,需要关注并适配翻译后文本内容过长而“溢出”的异常情况。
文本规范(高优) 微信小程序翻译功能仅适用于文本翻译,无法识别图片中的文字。开发者在微信小程序页面设计上,避免使用图片代替文字,尽可能确保文本表达清晰、直观。
词库维护 为确保开发者微信小程序中专有名词(如品牌名、产品词)翻译准确,平台支持开发者在微信公众平台维护自身微信小程序的翻译词库(微信小程序名称、品牌词、产品词、专业词汇等)
1. 登录微信公众平台前往「基础功能-翻译」下载翻译词库文件模版,填写词库文件上传

2. 确认翻译词库内容无误后,点击【确认生效】,当前平台审核版本的词库将正式生效

请注意:
• 翻译词库文件模版如下

• 翻译词库Excel文件首列为微信小程序主语言,若微信小程序主语言为中文,则将中文放在A列;若微信小程序主语言为英文,则将英文放在A列,以此类推;
• 若商户仅维护部分语言版本,在其余语言版本的翻译内容为空即可;
翻译动态适配 开发者可通过wx.onUserTriggerTranslation监听用户触发微信小程序的翻译功能事件,并动态将页面核心内容(品牌词、产品词等)调整为目标翻译语言,平台识别到该内容已经为目标翻译语言后,将不会二次翻译。
示例:
1. 监听到用户开启翻译功能,目标语言为阿拉伯语
2. 开发者将页面内商品名称修改成阿拉伯语的专有词汇,其他内容不做翻译
3. 平台识别到商品名称已经是阿拉伯语,不做二次翻译,只翻译其他内容

微信小程序翻译功能说明

  • 设置翻译语言:目标翻译语言默认为微信客户端使用的语言。若需要调整翻译语言,用户可进入“我” – “设置” – “通用” – “翻译”从语言列表中选择翻译语言。
  • 打开微信小程序翻译:可使用两种方式(1)进入微信小程序,若右上角显示“翻译”气泡,点击“翻译”按钮;(2)点击微信小程序右上角的 “…” 按钮,在弹窗点击“翻译”按钮;
  • 微信小程序翻译支持 18 种语言:简体中文、繁体中文(台湾)、繁体中文(香港)、英语、印度尼西亚语、马来语、西班牙语、韩语、意大利语、日语、葡萄牙语、俄语、泰语、越南语、阿拉伯语、土耳其语、德语、法语

3.2 开发者自行适配多语言界面

开发者可通过以下两种接口感知用户客户端语言/目标翻译语言,并自行适配多语言:

  • 开发者可通过wx.getAppBaseInfo接口,根据返回的language字段,获取用户客户端语言版本,在微信小程序内适配用户语言,并内置多语言切换功能。
  • 开发者可通过wx.onUserTriggerTranslation监听用户触发微信小程序的翻译功能事件,动态将页面的核心内容进行多语言适配。
  • 若微信小程序的界面营销玩法较为复杂(如弹窗广告、裂变分享、积分任务)对于外国游客来说,理解成本极高且容易被视为干扰信息,同时可能造成页面自动翻译后的排版混乱。开发者可考虑通过识别系统语言实施差异化的微信小程序界面
建议 说明
智能路由分流(核心逻辑) • 开发者可通过 wx.getAppBaseInfo 接口获取用户客户端语言版本(language 字段)
• 当检测到非中文语言环境时,微信小程序自动加载国际化界面
UI设计做减法 • 聚焦核心功能:针对国际版界面,可移除复杂的营销弹窗、会员任务体系及非必要的社交裂变入口,只保留点餐、购票、支付、客服、地图等微信小程序自身核心服务路径。
• 视觉通用化:增加通用图标与示意图的使用比例,减少对纯文本说明的依赖,降低跨文化理解门槛。

四、双语物料

平台提供中英双语微信小程序物料设计指引供商户更新线下物料,外国人线下扫码体验更友好;

微信小程序用户隐私保护指引内容介绍

本指引依据适用的个人信息保护相关法律法规制定,包括但不限于《中华人民共和国个人信息保护法》等,由开发者根据实际情况填写。

微信小程序用户隐私保护指引包括下列板块,其中具体的说明仅为示例。

引导语

  本指引是微信小程序示例微信小程序开发者”深圳市腾讯计算机系统有限公司“(以下简称“开发者”)为处理你的个人信息而制定。

开发者处理的信息

  根据法律规定,开发者仅处理实现微信小程序功能所必要的信息。
  - 开发者收集你选中的照片或视频信息,用于用户上传提交代码审核所需要的截图。

开发者需在此板块声明所处理的用户信息,微信会根据微信小程序版本隐私接口调用情况展示必填项,开发者可自主勾选其他项目。隐私接口与对应的处理的信息关系如下:

处理的信息 接口或组件
收集你的昵称、头像 <button open-type="chooseAvatar"><input type="nickname">、wx.getUserInfo (已回收)、wx.getUserProfile (已回收)、<button open-type="userInfo">(已回收)
收集你的位置信息 wx.authorize({scope:’scope.userLocation’})、wx.authorize({scope: ‘scope.userLocationBackground’})、wx.authorize({scope: ‘scope.userFuzzyLocation’})、wx.getLocation、wx.startLocationUpdate、wx.startLocationUpdateBackground、wx.getFuzzyLocation、MapContext.moveToLocation
收集你选择的位置信息 wx.choosePoi、wx.chooseLocation
收集你的地址 wx.chooseAddress
收集你的发票信息 wx.chooseInvoiceTitle、wx.chooseInvoice
收集你的微信运动步数 wx.authorize({scope: ‘scope.werun’})、wx.getWeRunData
收集你的手机号 <button open-type="getPhoneNumber"><button open-type="getRealtimePhoneNumber">
收集你的车牌号 wx.chooseLicensePlate
收集你选中的照片或视频信息 wx.chooseImage、wx.chooseMedia、wx.chooseVideo
收集你选中的文件 wx.chooseMessageFile
访问你的麦克风 wx.authorize({scope: ‘scope.record’})、wx.startRecord、RecorderManager.start、<live-pusher>、wx.joinVoIPChat
访问你的摄像头 wx.authorize({scope: ‘scope.camera’})、wx.createVKSession、<camera><live-pusher><voip-room>
访问你的蓝牙 wx.authorize({scope: ‘scope.bluetooth’})、wx.openBluetoothAdapter、wx.createBLEPeripheralServer
使用你的相册(仅写入)权限 wx.authorize({scope: ‘scope.writePhotosAlbum’})、wx.saveImageToPhotosAlbum、wx.saveVideoToPhotosAlbum
使用你的通讯录(仅写入)权限 wx.authorize({scope: ‘scope.addPhoneContact’})、wx.addPhoneContact
使用你的日历(仅写入)权限 wx.authorize({scope: ‘scope.addPhoneCalendar’})、wx.addPhoneRepeatCalendar、wx.addPhoneCalendar
调用你的加速传感器 wx.startAccelerometer
调用你的磁场传感器 wx.startCompass
调用你的方向传感器 wx.startDeviceMotionListening
调用你的陀螺仪传感器 wx.startGyroscope
读取你的剪切板 wx.setClipboardData、wx.getClipboardData

平台会对开发者处理信息的目的进行审核,请如实填写。

第三方插件信息

  为实现特定功能,开发者可能会接入由第三方提供的插件。第三方插件的个人信息处理规则,请以其公示的官方说明为准。XXX微信小程序接入的第三方插件信息如下:

  插件名称:客服助手
  插件提供方名称: 深圳市腾讯计算机系统有限公司
  - 开发者收集你选中的照片或视频信息,用于在客服会话中发送图片或视频类型的聊天内容。
  - 为了发送语音类型的聊天内容,开发者将在获取你的明示同意后,访问你的麦克风。

针对由引用了插件的微信小程序,将会在用户隐私保护指引中展示,展示内容包括插件名称、插件提供方名称与开发者处理的信息及目的。

第三方服务商信息

  微信小程序助手微信小程序由深圳市腾讯计算机系统有限公司代为开发,开发者保证深圳市腾讯计算机系统有限公司将在本指引规定范围内处理你的信息。

针对由代开发服务商进行开发的微信小程序,将会在用户隐私保护指引中进行展示。

用户权益

  1. 关于收集你的位置信息,你可以通过以下路径:微信小程序主页右上角“…”—“设置”—点击特定信息—点击“不允许”,撤回对开发者的授权。
  2. 关于收集你的手机号、收集你的发票信息,你可以通过以下路径:微信小程序主页右上角“...” — “设置” — “微信小程序已获取的信息” — 点击特定信息 — 点击“通知开发者删除”,开发者承诺收到通知后将删除信息。
  3. 关于你的个人信息,你可以通过以下方式与开发者联系,行使查阅、复制、更正、删除等法定权利。
  - 邮箱: miniprogram@tencent.com

微信会根据微信小程序版本隐私接口调用情况生成第1条与第2条描述,开发者需填写联系方式供用户联系开发者用于行使查阅、复制、更正、删除等法定权利。

若开发者在微信小程序内提供其他的用户可以行使查阅、复制、更正、删除等法定权利的入口,可以通过补充文档进行说明。

开发者对信息的存储

开发者需声明对信息的存储期限,如

  固定存储期限:180天

信息的使用规则

  1. 开发者将会在本指引所明示的用途内使用收集的信息。
  2. 如开发者使用你的信息超出本指引目的或合理范围,开发者必须在变更使用目的或范围前,再次以弹窗方式告知并征得你的明示同意。

信息对外提供

  1. 开发者承诺,不会主动共享或转让你的信息至任何第三方,如存在确需共享或转让时,开发者应当直接征得或确认第三方征得你的单独同意。
  2. 开发者承诺,不会对外公开披露你的信息,如必须公开披露时,开发者应当向你告知公开披露的目的、披露信息的类型及可能涉及的信息,并征得你的单独同意。

联系方式

  你认为开发者未遵守上述约定,或有其他的投诉建议、或未成年人个人信息保护相关问题,可通过以下方式与开发者联系;或者向微信进行投诉。
  - 邮箱 : miniprogram@**.com

补充文档

开发者可选择是否上传补充文档,微信会对文档内容进行审核。

当前文档格式只支持txt格式的纯文本文件,大小不超过100KB。

日期

  更新日期:2021-11-03
  生效日期:2021-11-03

插件用户隐私保护说明内容介绍

微信插件用户隐私保护说明包括下列板块,其中具体的说明仅为示例。

插件基本信息

包括插件名称、插件提供方名称。

  插件名称:客服助手
  插件提供方名称: 深圳市腾讯计算机系统有限公司

插件处理的信息

开发者需在此板块声明所处理的用户信息,微信小程序会根据插件版本隐私接口调用情况展示必填项,开发者可自主勾选其他项目。

  - 开发者收集你选中的照片或视频信息,用于在客服会话中发送图片或视频类型的聊天内容。
  - 为了发送语音类型的聊天内容,开发者将在获取你的明示同意后,访问你的麦克风。

隐私接口与对应的处理的信息关系如下:

处理的信息 接口或组件
收集你的昵称、头像 <button open-type="chooseAvatar"><input type="nickname"><functional-page-navigator name="loginAndGetUserInfo">、wx.getUserInfo (已回收)
收集你的位置信息 wx.authorizeForMiniProgram({scope:’scope.userLocation’})、wx.getLocation、wx.startLocationUpdate、wx.getFuzzyLocation
收集你选择的位置信息 wx.choosePoi、wx.chooseLocation
收集你的地址 wx.chooseAddress
收集你的发票信息 wx.chooseInvoiceTitle、wx.chooseInvoice
收集你选中的照片或视频信息 wx.chooseImage、wx.chooseMedia、wx.chooseVideo
访问你的麦克风 wx.authorizeForMiniProgram({scope: ‘scope.record’})、wx.startRecord、RecorderManager.start、<live-pusher>、wx.joinVoIPChat
访问你的摄像头 wx.authorizeForMiniProgram({scope: ‘scope.camera’})、wx.createVKSession、<camera><live-pusher><voip-room>
访问你的蓝牙 wx.openBluetoothAdapter、wx.createBLEPeripheralServer
使用你的相册(仅写入)权限 wx.authorizeForMiniProgram({scope: ‘scope.writePhotosAlbum’})、wx.saveImageToPhotosAlbum、wx.saveVideoToPhotosAlbum
使用你的通讯录(仅写入)权限 wx.addPhoneContact
调用你的加速传感器 wx.startAccelerometer
调用你的磁场传感器 wx.startCompass
调用你的方向传感器 wx.startDeviceMotionListening
调用你的陀螺仪传感器 wx.startGyroscope
读取你的剪切板 wx.setClipboardData、wx.getClipboardData