什么是组件化开发
微信小程序的组件和Vue的组件非常相似。
在微信小程序中有很多内置组件,比如button view input image等,有时候我们要自定义组件。和Vue的组件似的。
如何创建自定义组件:
新建一个components目录,在里边创建自定义组件
组件的组成:
- json
- js
- wxml
- wxss
使用组件:
- 在页面的.json中,usingComponents里写入该组件,声明一下。
- 在页面.wxml中使用,和内置组件一样。和Vue很相似
一个简单的示例:
创建comp,代表页面;创建components/xxxx,代表组件。
创建组件:
f-test.wxml
<view class="content">这里是内容</view>
<f-son />
f-test.json
{
"component": true, // 必须写了这句话,才代表这是一个组件
"usingComponents": { // 自定义组件中也可以引入其他组件
"f-son": "/components/f-son/f-son"
}
}
使用组件:
comp.json: 引入组件
{
"usingComponents": {
"f-test": "/components/f-test/f-test"
}
}
comp.wxml: 使用组件
<f-test />
注意:json文件中不能写注释啥的。这里的注释是为了解释清楚,在开发中不能写注释。
注意事项
组件的注意事项:
- wxml中,标签名只支持小写字母,中划线和下划线(一般只用中划线,和官方保持一致)。可以用数字。
- 自定义组件内部也可以去引用其他的自定义组件。
- 给自定义组件起名字的时候,不要以wx-开头,会报错。
- json文件中不可以有注释。
- 当很多页面都想要引入一个自定义组件的时候,就把它注册在全局的app.json中,这样所有的页面和自定义组件中都可以用这个组件了。但是不推荐这种做法。
组件的样式细节:
- 自定义组件的样式不会影响页面,页面的样式也不会对自定义组件造成影响。他们之间不会相互影响。前提是:使用class,会有隔离。
-
组件中
不允许使用id或者标签或者属性选择器。会包一个警告。
如何控制页面和组件的样式相互影响:
- 在组件的js文件中有个options属性,设置即可。
test.js:
options: {
styleIsolation: "shared",
}
取值:shared(相互作用),apply-shared(页面作用到组件,组件不作用到页面), isolate(相互隔离,默认)
组件和页面相互通信
组件和页面相互通信
- 页面-》组件,数据,properties
- 页面-》组件,样式,externalClasses
- 页面-》组件,标签,slot
- 组件-》页面,自定义事件,比如组件被点击了一下。this.triggerEvent
this.triggerEvent(事件名,参数对象,{}),最后是options,额外的一些选项
页面向组件传递数据和样式
// components/f-prop/f-prop.js
Component({
// 传递数据
properties: {
title: {
type: String, // 类型
value: "默认标题", // 默认值
observer: function(newVal, oldVal){ // 观察者
console.log(newVal, oldVal);
}
}
},
// 传递样式
externalClasses: ["contentclass"],
})
<!--components/f-prop/f-prop.wxml-->
<view class="title">{{ title }}</view>
<view class="content contentclass">这是内容</view>
使用:
<!--pages/comp/comp.wxml-->
<f-prop title="title1" contentclass="red" />
<f-prop title="title2" contentclass="green" />
<f-prop title="title3" contentclass="blue" />
/* pages/comp/comp.wxss */
.red{
color: red;
}
.green{
color: green;
}
.blue{
color: blue;
}
slot插槽
预留一个设备,以有利于对以后进行扩展。
好处:
- 组件的插槽让我们封装的组件更加具备扩展性
- 让使用者决定组件内部的一些内容到底展示什么
例子:
在移动端,导航栏,nav-bar,分为左中右三部分。不把这三部分的内容写死。就用插槽,为了封装性更好。
单个插槽的使用
单个插槽的使用很简单:
<!--components/f-slot-single/f-slot-single.wxml-->
<view>这是单个插槽的头部</view>
<slot />
<view>这是单个插槽的尾部</view>
<!--pages/comp/comp.wxml-->
<f-slot-single>
<button>这是单个插槽的button</button>
</f-slot-single>
<f-slot-single>
<text>这是单个插槽的文本内容</text>
</f-slot-single>
多个插槽的使用
多个插槽的使用稍微复杂,要设置几个东西:
<!--components/f-slot-multiple/f-slot-multiple.wxml-->
<view>这是多插槽的头部</view>
<slot name="left" />
<slot name="center" />
<slot name="right" />
<view>这是多插槽的尾部</view>
// components/f-slot-multiple/f-slot-multiple.js
Component({
options: {
multipleSlots: true, // 多个插槽要开启这个
},
});
<!--pages/comp/comp.wxml-->
<f-slot-multiple>
<button slot="left">这是多插槽的左边</button>
<button slot="center">这是多插槽的中间</button>
<button slot="right">这是多插槽的右边</button>
</f-slot-multiple>
component构造器
传递哪些东西 | 作用 | 示例 |
---|---|---|
options | 定义组件的配置选项 | multipleSlots: true / styleIsolation: shared |
data | 定义组件内部的初始化数据 | |
methods | 定义组件的内部函数 | |
properties | 让组件使用者可以给组件传递数据 | |
externalClasses | 外界给组件传递额外的样式 | 数组 |
observers | 可以监听属性的改变 |
component构造器中可以写哪些东西,如下
// components/f-slot-multiple/f-slot-multiple.js
Component({
// 1. 额外的配置
options: {
multipleSlots: true, // 多个插槽要开启这个
styleIsolation: "shared", // 页面和组件的样式共享方式
},
// 2. 页面给组件传递数据
properties: {
title: {
type: String,
value: "",
oberver: function(newVal, oldVal){}
}
},
// 3. 组件内部的数据
data: {
message: ""
},
// 4. 组件内部方法
methods: {
},
// 5. 页面向组件传递样式
externalClasses: ["contentclass"],
// 6. 监听properties和data的变化
observers: {
title: function(newVal){ // 没有oldVal
},
message: function (newVal) { }
},
// 7. 组件的生命周期
// 7.1 监听所在页面的生命周期
pageLifetimes: {
show(){
console.log("监听组件所在的页面显示时");
},
hide(){
console.log("监听组件所在页面隐藏时");
},
resize(){
console.log("监听组件所在页面的页面尺寸发生变化时");
}
},
// 7.2 监听组件本身的生命周期
lifetimes: {
created(){
console.log("组件被创建出来");
},
attached(){
console.log("组件被添加到页面/其他组件");
},
ready(){
console.log("组件被渲染出来时");
},
move(){
console.log("组件从一个地方移到另一个地方");
},
detached(){ // 可以wx:if来验证。
console.log("组件被移除掉");
}
}
})
网友评论