Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

WeChat gadgets component templates and styles


May 17, 2021 WeChat Mini Program Development Document



Component templates and styles

Similar to a page, custom components have their own wxml templates and wxs styles.

The component template

Component templates are written in the same way as page templates. The node tree that is generated when the component template is combined with the component data is inserted into the reference location of the component.

In the component template, you can provide a node that is used to host the child nodes that are provided when the component references.

Code example:

<!-- 组件模板 -->
<view class="wrapper">
  <view>这里是组件的内部节点</view>
  <slot></slot>
</view>
<!-- 引用组件的页面模板 -->
<view>
  <component-tag-name>
    <!-- 这部分内容将被放置在组件 <slot> 的位置上 -->
    <view>这里是插入到组件slot中的内容</view>
  </component-tag-name>
</view>

Note that the custom components referenced in the template and their corresponding node names need to be explicitly defined in the json file, otherwise they are treated as meaningless nodes. In addition, node names can also be declared abstract nodes.

Template data binding

Similar to a normal WXML template, you can use data binding so that you can pass dynamic data to the properties of sub-components.

Code example:

<!-- 引用组件的页面模板 -->
<view>
  <component-tag-name prop-a="{{dataFieldA}}" prop-b="{{dataFieldB}}">
    <!-- 这部分内容将被放置在组件 <slot> 的位置上 -->
    <view>这里是插入到组件slot中的内容</view>
  </component-tag-name>
</view>

In the above example, the component's properties propA and propB receive the data passed by the page. The page can change the bound data field by setData.

Note: This data binding can only pass JSON-compatible data. Starting with the underlying library version 2.0.9, you can also include functions in your data (but they cannot be called directly in WXML and can only be passed to sub-components).

The slot of the component wxml

Slot nodes can be included in the wxml of a component to host the wxml structure provided by the component consumer.

By default, there can only be one slot in the wxml of a component. When you need to use multiple slots, you can declare enable in component js.

Component({
  options: {
    multipleSlots: true // 在组件定义时的选项中启用多slot支持
  },
  properties: { /* ... */ },
  methods: { /* ... */ }
})

At this point, you can use multiple slots in the wxml of this component, distinguished by different names.

<!-- 组件模板 -->
<view class="wrapper">
  <slot name="before"></slot>
  <view>这里是组件的内部细节</view>
  <slot name="after"></slot>
</view>

When used, use the slot property to insert nodes into different slots.

<!-- 引用组件的页面模板 -->
<view>
  <component-tag-name>
    <!-- 这部分内容将被放置在组件 <slot name="before"> 的位置上 -->
    <view slot="before">这里是插入到组件slot name="before"中的内容</view>
    <!-- 这部分内容将被放置在组件 <slot name="after"> 的位置上 -->
    <view slot="after">这里是插入到组件slot name="after"中的内容</view>
  </component-tag-name>
</view>

Component style

The style of the component corresponds to the wxs file and takes effect only for nodes within the component wxml. When writing component styles, you need to be aware of the following:

  • The id selector (#a), the property selector (a) and the label name selector cannot be used on the component and the page that references the component.
  • Descendant selectors (.a .b) used in the pages of components and reference components can behave un expectablely in some extreme situations and should be avoided in the event of such a situation.
  • The child element selector (.a>.b) can only be used between the view component and its child nodes, and for other components that can cause unannored conditions.
  • Inheritance styles, such as font, color, are inherited from outside the component to the component.
  • In addition to inherited styles, styles in app.wxss, and the style of the page on which the component is located are not valid for custom components (unless you change the component style isolation option).
#a { } /* 在组件中不能使用 */
[a] { } /* 在组件中不能使用 */
button { } /* 在组件中不能使用 */
.a > .b { } /* 除非 .a 是 view 组件节点,否则不一定会生效 */

In addition, the component can specify the default style of the node in which it is located, using the :host selector, which requires developer tool support that includes the underlying library 1.7.2 or later.

Code example:

/* 组件 custom-component.wxss */
:host {
  color: yellow;
}
<!-- 页面的 WXML -->
<custom-component>这段文本是黄色的</custom-component>

Component style isolation

By default, the style of a custom component is only affected by the custom component wxss. Unless there are two scenarios:

  • App.wxss or the wxss of a page use tag name selectors (or some other special selectors) to specify styles directly, which affect the page and all components. Usually this is not recommended.
  • Specify a special style isolation option, styleIsolation.
Component({
  options: {
    styleIsolation: 'isolated'
  }
})

The styleIsolation option starts with base library version 2.6.5. It supports the following values:

  • Isolated means that style isolation is enabled, and styles specified with class will not affect each other inside or outside the custom component (the default in general);
  • Apply-shared means that the page wxss style will affect the custom component, but the style specified in the custom component wxss will not affect the page;
  • Shared means that the page wxs style affects custom components, and the styles specified in the custom component wxss also affect the page and other custom components that have apply-shared or shared set. ( This option is not available in the plug-in.)

When using the 3d, it is important to be aware of the inter-component styles.

If this Component constructor is used to construct a page, the default value is shared, and there are several additional style isolation options available:

  • page-isolated means that app.wxss is disabled on this page, and that the wxss of the page does not affect other custom components;
  • page-apply-shared means that app.wxss is disabled on this page, while the page wxss style does not affect other custom components, but custom components set to shared affect the page;
  • Page-shared means that app.wxss is disabled on this page, and the page wxss style affects other custom components that are set to apply-shared or shared, as well as custom components that are set to shared.

Starting with the small program base library version 2.10.1, you can also configure styleIsolation in the json file of a page or custom component (so that you don't have to configure it in the options of the js file). For example:

{
  "styleIsolation": "isolated"
}

In addition, the addGlobalClass option is supported above the small program base library version 2.2.3, i.e. addGlobalClass: true is set in Component's options. This option is equivalent to setting styleIsolation: apply-shared, but this option expires when the styleIsolation option is set.

Code example:

/* 组件 custom-component.js */
Component({
  options: {
    addGlobalClass: true,
  }
})
<!-- 组件 custom-component.wxml -->
<text class="red-text">这段文本的颜色由 `app.wxss` 和页面 `wxss` 中的样式定义来决定</text>
/* app.wxss */
.red-text {
  color: red;
}

The external style class

Base library 1.9.90 starts to support, and low versions need to be compatible.

Sometimes, components want to accept externally passed-in style classes. At this point, you can define several external style classes in Component with externalClasses definition segments.

This attribute can be used to implement the hover-class property similar to the view component: the page can provide a style class that gives the view hover-class, which itself is written on the page rather than in the implementation of the view component.

Note: When using normal and external style classes on the same node, the priority of both classes is undefined, so it is best to avoid this situation.

Code example:

/* 组件 custom-component.js */
Component({
  externalClasses: ['my-class']
})
<!-- 组件 custom-component.wxml -->
<custom-component class="my-class">这段文本的颜色由组件外的 class 决定</custom-component>

In this way, the consumer of the component can specify the class for this style class, just as it would with normal properties. After 2.7.1, you can specify more than one corresponding class.

Code example:

<!-- 页面的 WXML -->
<custom-component my-class="red-text" />
<custom-component my-class="large-text" />
<!-- 以下写法需要基础库版本 2.7.1 以上 -->
<custom-component my-class="red-text large-text" />
.red-text {
  color: red;
}
.large-text {
  font-size: 1.5em;
}

The style that refers to the page or parent component

Base library 2.9.2 starts to support, and low versions need to be compatible.

Even if style isolation is enabled, components can still locally reference the style of the page on which the component is located or the style of the parent component.

For example, if you define it in page wxss:

.blue-text {
  color: blue;
}

In this component, you can refer to the style of this class by using .

<view class="~blue-text"> 这段文本是蓝色的 </view>

If the parent component of a component is defined in wxss:

.red-text {
  color: red;
}

In this component, you can refer to the style of this class by using .

<view class="^red-text"> 这段文本是红色的 </view>

You can also use more than one s in a row to refer to styles in ancestor components.

Note: If the component is a relatively independent, generic component, use the external style class as a priority over referencing the style of the parent component or page directly.

Virtualize component nodes

Base library 2.11.2 starts to be supported, and low versions need to be compatible.

By default, the node of the custom component itself is a "normal" node on which class style, animation, flex layout, and so on can be set, just like a normal view component node.

<!-- 页面的 WXML -->
<view style="display: flex">
  <!-- 默认情况下,这是一个普通的节点 -->
  <custom-component style="color: blue; flex: 1">蓝色、满宽的</custom-component>
</view>

Sometimes, however, custom components do not want the node itself to style, respond to flex layouts, and so on, but rather that the first layer of nodes within the custom component responds to the flex layout or that the style is entirely determined by the custom component itself.

In this case, you can set this custom component to Virtual:

Component({
  options: {
    virtualHost: true
  },
  properties: {
    style: { // 定义 style 属性可以拿到 style 属性上设置的值
      type: String,
    }
  },
  externalClass: ['class'], // 可以将 class 设为 externalClass
})

This allows you to put flex into a custom component:

<!-- 页面的 WXML -->
<view style="display: flex">
  <!-- 如果设置了 virtualHost ,节点上的样式将失效 -->
  <custom-component style="color: blue">不是蓝色的</custom-component>
</view>
<!-- custom-component.wxml -->
<view style="flex: 1">
  满宽的
  <slot></slot>
</view>

Note that class styles and animations on custom component nodes no longer take effect, but can still:

  • Define the style as a properties property to get the value set on the style;
  • Defining class as an externalClasses external style class allows the custom component wxml to use the class value.