小程序在使用时,经常会在不同的页面用到相同的页面结构,这个时候我们如果一个个写的话没有必要,这个时候可以使用模板(template)或者组件(component)。
二者区别在于:
- 模板通常是用于纯展示的元素,不做JS操作,
- 组件是单独的,类似于页面,自定义组件拥有自己的 wxml 模板和 wxss 样式,交互逻辑较多。
模板使用:官方文档
1、需要定义模板:一个template.wxml文件中能写多个模板,用name区分,
下面定义两个模板
<!-- 提示 -->
<template name="noContent">
<view class="noContent" hidden="{{!show}}">
<view wx:if="{{type==2}}">暂无内容</view>
<view wx:elif="{{type==5}}">暂无用户</view>
<view wx:else>{{text}}</view>
</view>
</template>
<!-- 内容 -->
<template name="content">
<view>
<text>{{name}}: {{title}} </text>
<!-- 点击事件定义在引用模板的js文件里 -->
<text class="num" bindtap="subtractNum">get:{{num}}</text>
</view>
</template>
2、使用这两个模板,在对应的wxml文件引入:
<!--content.wxml-->
//导入模板
<import src="/pages/template/noContent.wxml" />
<view class="template">
<view class="title">template使用:</view>
<!-- 用is来定义使用哪个模板,对应的是模板的name data里是传的值,必须是对象-->
<template is="noContent" data="{{show:true,type:3,text:'下面是模板呈现的'}}"></template>
<view class="list" wx:for="{{contentList}}" wx:for-item="c_item" wx:key="contentId">
<template is="content" data="{{...c_item}}"></template>
</view>
</view>
// 模板可以定义自己的css样式,需要在使用模板的wxss页面引入:
<!--content.wxss-->
@import "/pages/template/noContent.wxss";
3、上面在模板content里定义了点击事件subtractNum方法,因为template中没有js文件,因此template中的点击事件,在使用页面中的js里定义。
// pages/useComponent/useComponent.js
const app = getApp();
const operate = require('../../utils/operate.js');
Page({
data: {
contentList: [
{
contentId: 1,
name: '张三',
num: 12,
sex: 1,
title: '这是一个简单的例子'
}
],
},
touchMe(){
operate.hintToast('触发点击')
}
})
建议将有子列表操作交互的写成component。
组件使用:官方文档
1、快捷创建组件,在对应的文件目录下,右键 - 新建component,会自动生成 四个文件,组件的结构和page的结构类似。在自定义组件的
js
文件中,需要使用Component()
来注册组件,并提供组件的属性定义、内部数据和自定义方法。
组件的属性值和内部数据将被用于组件wxml
的渲染,其中,属性值是可由组件外部传入的。更多细节参见 Component构造器
示例:
Component({
properties: {
// 这里定义了dto属性,属性值可以在组件使用时指定
dto: {
type: Object,
value: {},
}
},
data: {
// 这里是一些组件内部数据
someData: {}
},
methods: {
// 这里是一个自定义方法
addNum(event) {
let self = this;
let obj = this.properties.dto;
console.log(event);
let id = event.currentTarget.dataset.contentid;
obj.num = ++obj.num;
self.setData({
dto: obj
})
},
}
})
对应组件的wxml跟page里的wxml一样:
<!-- component.wxml -->
<view class="clearfix" data-contentid="{{item.contentId}}">
<view class="inco_list inco_praise" data-contentid="{{dto.contentId}}" catchtap="addNum">
<text>{{dto.name}}:{{dto.title}}</text>
<text class="num">get: {{dto.num}}</text>
</view>
</view>
2、使用自定义组件前,首先要在页面的 json 文件中进行引用声明。此时需要提供每个自定义组件的标签名和对应的自定义组件文件路径
{
"navigationBarTitleText": "组件使用",
"usingComponents": {
"content": "../components/content/content"
}
}
这样,在页面的 wxml 中就可以像使用基础组件一样使用自定义组件。节点名即自定义组件的标签名,节点属性即传递给组件的属性值。
<!-- useComponent.wxml -->
<view class="title">组件使用:</view>
<view class="list" wx:for="{{contentList}}" wx:key="contentId">
<content id="content" dto="{{item}}" ></content>
</view>
见图下一节将进入如何组件向父级传值(组件通信)