文章目录
组件化开发
1.创建一个自定义组件
类似于页面,自定义组件由json,wxml,wxss,js四个文件
在wxml文件中编写属于组件自己的模板
在wxss中编写属于组件的相关样式
在js文件中定义数据结构和相关逻辑
2.自定义组件的使用
以home页面为例:
1.先在home.json中进行注册
"usingComponents": {
"my-cpn" : "/components/my-cpn/my-cpn"
}
//注册形式: 标签名:组件的路径
//路径可以是相对路径,也可以是绝对路径
2.在home.wxml文件中使用注册的标签名进行使用
<!-- 1. 使用自定义组件 -->
<!-- 可以使用单标签,也可以使用双标签 -->
<my-cpn></my-cpn>
<my-cpn/>
3.强调:
自定义组件中json文件的内容不能随意修改,只有,component为true,这个组件才是自定义组件
{
"component": true,
"usingComponents": {}
}
4.使用自定义组件时的细节和注意事项:
- 自定义组件的标签名只能包含小写字母、中划线、下划线和数字
- 自定义组件的内部可以引用其他自定义组件,在自定义组件的json文件中
"usingComponents": {}
进行类似的注册就可以进行使用 - 自定义组件和页面所在项目根目录名不能以 **“wx-”**为前缀,否则会报错
- 注册全局组件,在app.json文件中定义"usingComponents"字段,然后将自定义组件进行注册,则该组件可以在全局使用
5.组件的样式细节
(1)组件内样式对外部影响
- 组件内的class样式,只对组件wxml内的节点生效,对于引用组件的page页面不生效
- 组件内不能使用id选择器、属性选择器、标签选择器
(2)外部样式对组件内样式的影响
- 外部使用的class样式,只对外部wxml的class生效,对组件内是不生效的
- 外部使用了id选择器、属性选择器不会对组建内部产生影响
- 外部使用了标签选择器,会对组件内部产生影响
(3)结论
- 组件内的class样式和组件外的class样式,默认有一个隔离效果;
- 为了防止错乱,官方不推荐自定义组件使用id、属性、标签选择器,使用类选择器
(4) 如何让class可以相互影响
在组件的js文件中的Component对象中传入options属性,改变该属性中styleIsolation的对应取值
三个取值:
- isolated 表示启用隔离样式
- apply-shared 表示wxss样式将影响到自定义组件,但自定义组件样式不会影响页面的样式
- shared 表示两者相互影响
//默认isolated,隔离的
options: {
styleIsolation: 'isolated'
}
6.组件和页面通信—给组建中传递数据和样式
页面向组件中传入:数据(properties)、样式(externalClass)、标签(slot);
组件向页面传入自定义事件
6.1向页面中传入数据:
第一种方式的步骤:
- 不能将要显示的内容写死;
<view class="title">{{title}}</view>
- 在组件的js文件中有properties属性,这个属性是专门定义组件属性列表,在这个属性中可以定义组件要接收的数据,并对这个数据的内容进行定义;
properties: {
title: String,
},
- 在使用组件时传入数据
<my-prop title="哈哈哈"/>
<my-prop title="呵呵呵"/>
<my-prop title="嘿嘿嘿"/>
第一种方式的缺点:没有默认值,页面当不传值时,将不会显示
优化:在定义属性时写成对象形式
title: {
type: String,
value: '我是默认的标题', //默认值
observer: function(newval, oldval){
console.log(newval, oldval);
//observer 用来监听值的改变,传递一个函数
}
}
6.2向页面传递样式
步骤:
(1)在需要页面传递样式的地方添加类名(组件wxml文件)
<view class="title titleclass">{{title}}</view>
(2)在js文件的 externalClasses 属性中的列表中添加该类名,此时将该类名传递给了调用该组件的页面;
externalClasses: ['titleclass']
(3)在使用该组件时将传递过来的类名重新赋值一个类名
<my-prop title="哈哈哈" titleclass="red"/>
<my-prop title="呵呵呵" titleclass="green"/>
<my-prop title="嘿嘿嘿" titleclass="blue"/>
<!-- red, green, blue是重新定义的类名 -->
(4)使用新的类名可以在页面的wxss文件中单独给组件定义样式
.red {
color: red;
}
.green {
color: green;
}
.blue {
color: blue;
}
6.3组件向外传递事件-自定义事件
步骤:
(1) 在wxml中定义该事件名
(2) 在js文件中定义该事件的函数,并使用函数将该事件传递出去
methods: {
handleIncrement(){
// console.log('---------------------');
this.triggerEvent('increment', {name: 'why', age: 18}, {})
//increment为传递出去的事件名称, 第二个参数是一些其他数据,在event事件中可以去个这些其他数据
}
}
(3)在使用组件的页面进行监听,然后重新定义事件
<view>当前计数Counter: {{counter}}</view>
<my-event bind:increment="handleIncrement"/>
handleIncrement(event){
console.log('---', event);
this.setData({
counter: this.data.counter + 1
})
},
6.4页面直接调用组件修改数据/方法
在组件的js文件中向外暴露一个方法
methods: {
incrementCounter(num){
this.setData({
counter: this.data.counter + num
})
}
}
通过id或者类名获取当前组件对象,然后后根据组件的方法对组件内的数据进行修改
const my_select = this.selectComponent('#select-id')
my_select.incrementCounter(1)
7.slot 插槽的使用
使用插槽的目的:使组件更具扩展性
在组件中使用多个插槽
使用步骤及注意事项:
- 使用多个插槽时,需要给每个插槽增加name属性(具名插槽)
//组件的wxml
<view>我是mslot组件的开始</view>
<view class="slot1"><slot name="slot1"/></view>
<view class="slot2"><slot name="slot2"/></view>
<view class="slot3"><slot name="slot3"/></view>
<view>我是mslot组件的结尾</view>
- 必须在Component对象中添加一个选项:options->multipleSlots: true
options: {
multipleSlots: true
}
- 根据插槽的name进行使用
<my-mslot>
<button slot="slot2">按钮</button>
<slider slot="slot1"></slider>
<text slot="slot3">哈哈哈</text>
</my-mslot>
8.Component构造器
Component中可以写那些东西,具体有什么作用
// components/my-cpn/my-cpn.js
Component({
/**
* 组件的属性列表
*/
//让使用者可以传入数据
properties: {
title: {
type: String,
value: ''
}
},
/**
* 组件的初始数据
*/
//定义组件内部的初始化数据
data: {
counter:0
},
/**
* 组件的方法列表
*/
//用于定义组件内部的函数
methods: {
foo(){}
},
//用于定义组件的配置选项
//multipleSlots: 使用多插槽时设置为true
// styleIsolation: 设置样式的隔离方式
options: {
},
//外界给组件传入额外的样式
externalClasses:[类名1,类名2],
//可以监听属性的改变
observers: {
//监听counter属性
counter: function(newval){
//counter值改变时,会将最新的值传过来,但是不会传递旧值
conslole.log(newval)
}
},
//---------------组件中监听生命周期函数----------
//1.监听所在页面的生命周期
pageLifetimes: {
show(){
conslole.log('监听组件所在页面是否显示出来了')
},
hide(){
conslole.log('监听组件所在页面隐藏起来时')
},
resize(){
conslole.log('监听组件所在页面尺寸改变')
}
},
//2.监听组件本身的生命周期
lifetimes: {
created(){
conslole.log('组件被创建出来时')
},
attached(){
conslole.log('组件被添加到页面或者其他组件')
},
ready(){
conslole.log('组件被渲染出来')
},
moved(){
conslole.log('组件被移动到另一个节点')
},
detached(){
conslole.log('组件被移除掉')
}
}
})