一周左右的时间, 和小程序渐渐的熟悉了起来,今天我们来聊一聊小程序组件--
component。
1. 为什么会有component?
刚开始入门的几天里最先接触到具有模块化概念的其实是template, 后面才接触到component。
猛然见感觉,这两个东西是不是有些重复?
下面我们来仔细分析一下:
首先看下template的例子:
template:
├── template
| ├── demo-template.wxml
| └── demo-template.wxss
demo-template.wxml
<template name="msgItem">
<view>
<text> {{index}}: {{msg}} </text>
<text> Time: {{time}} </text>
</view>
</template>
在父容器中引入
index.wxml
<!--引入template-->
<import src="../template/demo-template.wxml" />
<!--index.wxml-->
<view class="container">
<!--item为index.js中data定义的值,通过es6{{...item}}平铺展开-->
<template is="msgItem" data="{{...item}}"></template>
</view>
template通过上述方法拿到父容器的值,进行渲染。
这看起来完全只能作为数据展示用啊!!!好受限制的感觉!!!
看下官网 模版 介绍部分的最后一句。
模板拥有自己的作用域,只能使用 data 传入的数据 以及 模版定义文件中定义的 模块。
看下标红的部分,就是说,template只能获取父容器传来的数据,相对数据进行操作只能通过<wxs/>。
如下:
<template name="msgItem">
<wxs module="m1">
var msg = "hello world";
function changeMsg(msg) {
var msgChange = msg;
msgChange = "hello, msg is change!!"
return msgChange;
};
module.exports.message = msg;
module.exports.changeMsg = changeMsg;
</wxs>
<view>
<view> changebefore: {{msg}} </view>
<view> changeafter: {{m1.changeMsg(msg)}} </view>
<view> {{m1.message}}</view>
</view>
</template>
总结下template:
父组件每次想要使用模版都要import,有点麻烦,而且数据处理感觉不够灵活,比如父组件传递一个数据给到template, 这个时候template改动了这个数据,想传回给父组件,这个时候感觉就很吃力了(是不是很怀念react!!!)。
于是!!!诞生了好用的component。
官网对component的相关介绍:
看了这么多,实际来操作下吧!!!
核心逻辑:
-
定义组件:
-
compoennt.json中需要说明这是一个组件:
{ "component": true } -
compoennt.js中定义构造器: ```js Component({
behaviors: [], properties: { //父组件给过来的数据 myProperty: { // 属性名 type: String, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型) value: '', // 属性初始值(可选),如果未指定则会根据类型选择一个 observer: function(newVal, oldVal, changedPath) { // 属性被改变时执行的函数(可选),也可以写成在methods段中定义的方法名字符串, 如:'_propertyChange' // 通常 newVal 就是新设置的数据, oldVal 是旧数据 } }, myProperty2: String // 简化的定义方式 }, data: {}, // 私有数据,可用于模版渲染 // 生命周期函数,可以为函数,或一个在methods段中定义的方法名 attached: function(){}, moved: function(){}, detached: function(){}, methods: { onMyButtonTap: function(){ this.setData({ // 更新属性和数据的方法与更新页面数据的方法类似 }) }, // 内部方法建议以下划线开头 _myPrivateMethod: function(){ // 这里将 data.A[0].B 设为 'myPrivateData' this.setData({ 'A[0].B': 'myPrivateData' }) }, _propertyChange: function(newVal, oldVal) { } } }) ```
-
-
定义一个父组件:
index.json中配置需要的组件:
{
"usingComponents": {
<!--引用名:组件实际所在路径-->
"component-tag-name": "../components/cpt/cpt"
}
}
index.wxml引入组件:
<view>
<component-tag-name bindshow="onbindshow">
<!--slot点-->
<view></view>
</component-tag-name>
</view>
想要通过点击组件触发父级的onbindshow方法,需要在method中使用triggerEvent。
Component({
properties: {}
methods: {
onTap: function(){
var myEventDetail = {} // detail对象,提供给事件监听函数
var myEventOption = {} // 触发事件的选项
this.triggerEvent('show', myEventDetail, myEventOption)
}
}
})
总结:
component比较起template引入更加优雅,不需要在烦人的import。- 功能更强大,不但可以接受渲染数据,而且可以回传数据给父组件。
- template使用简单,需要建立的文件较少。
下方干货!!
因为实际工作中项目的原因,使用
<map>组件的情况比较多,所以特意写了一个小demo来熟悉,里面有具体的介绍,这里不在赘述: