创建微信小程序组件

在小程序中创建组件:

1、项目根目录中创建【components】目录,存放自定义组件

2、进入components目录,给组件创建一个组件目录

3、右键组件目录,选择【创建Components】

4、之后回车,会自动生成组件对应的4个文件, 后缀名分别为.js, .json, .wxml和.wxss

一、全局组件和局部组件

局部页面引用组件:

在【页面的.json】配置文件中引用组件的方式,叫做“局部引用”。

示例代码如下:

{
"usingComponents": {
"test1": "/components/test1/test1"
}
}

  

全局引用组件:

在【app.json】中配置组件信息

"usingComponents": {
"test1": "/components/test1/test1"
}

  

使用组件:

<!-- 全局可以在任意页面中使用引入的组件, 局部组件只允许在引入的页面中使用 -->
<test1></test1>

  

组件和页面的区别

从表面来看,组件和页面都是由.js、 json、 .wxml 和.WXSS这四个文件组成的。

但是,组件和页面的js与.json文件有明显的不同:

● 组件的 json文件中需要声明"component": true属性

● 组件的 js文件中调用的是Component()函数

● 组件的事件处理函数需要定义到methods节点中

二、组件之间的样式隔离问题:

一、组件样式隔离

默认情况下,自定义组件的样式只对当前组件生效,不会影响到组件之外的UI结构

● 组件A的样式不会影响组件C的样式
● 组件A的样式不会影响小程序页面的样式
● 小程序页面的样式不会影响组件A和C的样式

好处:

① 防止外界的样式影响组件内部的样式

② 防止组件的样式破坏外界的样式

二、组件样式隔离的注意点

● app.wxss中的全局样式对组件无效

● 只有class选择器会有样式隔离效果,
id选择器、属性选择器、标签选择器不受样式隔离的影响

建议:在组件和引用组件的页面中建议使用class选择器,不要使用id、属性、标签选择器!

三、修改组件的样式隔离选项

默认情况下,自定义组件的样式隔离特性能够防止组件内外样式互相干扰的问题。

但有时,我们希望在外界能够控制组件内部的样式,

此时,可以通过stylelsolation 修改组件的样式隔离选项,

用法如下:

// components/test1/test1.js
Component({
options: {
styleIsolation: 'isolated'
}
}) // components/test1/test1.json
{
"component": true,
"usingComponents": {},
"styleIsolation": "isolated"
}

  

四、 stylelsolation的可选值

isolated
  表示启用样式隔离,在自定义组件内外,使用class指定的样式将不会相互影响 apply-shared
  表示页面WXSs样式将影响到自定义组件,但自定义组件wxSS中指定的样式不会影响页面

shared
  表示页面WxSs样式将影响到自定义组件,
  自定义组件Wxss中指定的样式也会影响页面和其他设置了apply-shared或shared的自定义组件

  

三、Data属性 和 Method方法

和页面一样设置

/**
* 组件的初始数据
*/
data: {
count: 0
},

方法是独立的一个对象存放

  /**
* 组件的方法列表
* 在这里编写自定义方法,和事件处理函数
* 自定义方法推荐使用下划线前缀标记
* 如:
* addCount() // 事件执行方法
* _showCount() // 自定义方法
*/
methods: {
addCount() {
this.setData({ count: this.data.count + 1})
this._showCount()
},
_showCount() {
wx.showToast({
icon: 'none',
title: `count值:${this.data.count}`
})
}
}

 

四、Properties属性

  /**
* 组件的属性列表
* 用来接收外部页面或者其他组件传递进来的属性
*/
properties: {
// 和vue一样的写法
max: {
type: Number,
value: 10 // 默认值
}
/**
* 简化写法,不设置默认值
* max: Number
*/
},

  

组件使用时可以设置值

<test1 max="{{5}}"/>

  

使用propertis数据

等于max值时无法继续叠加

addCount() {
if (this.data.count === this.properties.max) return
this.setData({ count: this.data.count + 1})
this._showCount()
},

  

五、data和properties的区别

在小程序的组件中,properties 属性和data数据的用法相同,它们都是可读可写的,只不过:

● data更倾向于存储组件的私有数据

● properties更倾向于存储外界传递到组件中的数据

两者的地址一致:

this.data === this.properties // true

给properties属性赋值

// 为properties的数据重新赋值
this.setData({ max: this.properties.max + 1 })

  

六、数据监听器

监听器功能再页面不支持

/**
* 组件的数据监听器
*/
observers: {
// 可以同时监听多个属性, 入参的参数对应属性个数,表示属性更新后的值
'attr1, attr2': function(newValue1, newValue2) {
// todo ...
}
},

演示案例:

组件HTML代码:

<!--components/test2/test2.wxml-->
<text>components/test2/test2.wxml</text> <view>
{{n1}} + {{n2}} = {{sum}}
</view>
<button size="mini" type="primary" bindtap="addN1">n1增加</button>
<button size="mini" type="primary" bindtap="addN2">n2增加</button>

组件JS代码:

// components/test2/test2.js
Component({
/**
* 组件的数据监听器
*/
observers: {
'n1, n2': function(n1Value, n2Value) {
this.setData({ sum: n1Value + n2Value })
}
},
/**
* 组件的属性列表
*/
properties: { }, /**
* 组件的初始数据
*/
data: { n1: 0, n2: 0, sum: 0 }, /**
* 组件的方法列表
*/
methods: {
addN1() { this.setData({ n1: this.data.n1 + 1 }) },
addN2() { this.setData({ n2: this.data.n2 + 1 }) }
}
}) 

演示案例2:

一个RGB颜色案例,HTML代码

<!--components/rgbView/rgbView.wxml-->
<text>components/rgbView/rgbView.wxml</text> <view class="colorBox" style="background-color: rgb({{fullColor}});">
颜色值:{{fullColor}}
</view>
<button size="mini" bindtap="changeR" >R</button> |
<button size="mini" bindtap="changeG" >G</button> |
<button size="mini" bindtap="changeB" >B</button>
<view>
{{rgb.r}}, {{rgb.g}}, {{rgb.b}}
</view>

  

JS代码:

// components/rgbView/rgbView.js
Component({
observers: {
// 监听,然后重新赋值
'rgb.**': function(newRgb) {
this.setData({
fullColor: `${newRgb.r}, ${newRgb.g}, ${newRgb.b}`
})
}
}, /**
* 组件的属性列表
*/
properties: { }, /**
* 组件的初始数据
*/
data: {
rgb: { r: 0, g: 0, b: 0 },
fullColor: '0, 0, 0'
}, /**
* 组件的方法列表
*/
methods: {
changeR() {
let rValue = this.data.rgb.r + 5
rValue = rValue > 255 ? 255 : rValue
this.setData({ 'rgb.r': rValue })
},
changeG() {
let gValue = this.data.rgb.g + 5
gValue = gValue > 255 ? 255 : gValue
this.setData({ 'rgb.g': gValue })
},
changeB() {
let bValue = this.data.rgb.b + 5
bValue = bValue > 255 ? 255 : bValue
this.setData({ 'rgb.b': bValue })
}
}
})

RGB显示板样式:

/* components/rgbView/rgbView.wxss */
.colorBox {
line-height: 200rpx;
font-size: 24rpx;
color: white;
text-shadow: 0rpx 0rpx 2rpx black;
text-align: center;
}

  

七、纯数据字段

1.什么是纯数据字段

概念:纯数据字段指的是那些不用于界面渲染的data字段。
应用场景:例如有些情况下,某些data中的字段既不会展示在界面上,也不会传递给其他组件,仅仅在当前
组件内部使用。带有这种特性的data字段适合被设置为纯数据字段。

好处:纯数据字段有助于提升页面更新的性能。

2.使用规则

在Component构造器的options节点中,指定pureDataPattern为一个正则表达式,

字段名符合这个正则表达式的字段将成为纯数据字段,示例代码如下:

// components/rgbView/rgbView.js
Component({
options: {
// 自定义正则规则来匹配纯数据字段,演示为首字符下划线的属性
pureDataPattern: /^_/
}
}

把之前的JS代码的rgb属性名改为_rgb使用即可:

// components/rgbView/rgbView.js
Component({
options: {
// 自定义正则规则来匹配纯数据字段,演示为首字符下划线的属性
pureDataPattern: /^_/
},
observers: {
// 监听,然后重新赋值
'_rgb.**': function(newRgb) {
this.setData({
fullColor: `${newRgb.r}, ${newRgb.g}, ${newRgb.b}`
})
}
}, /**
* 组件的属性列表
*/
properties: { }, /**
* 组件的初始数据
*/
data: {
_rgb: { r: 0, g: 0, b: 0 },
fullColor: '0, 0, 0'
}, /**
* 组件的方法列表
*/
methods: {
changeR() {
let rValue = this.data._rgb.r + 5
rValue = rValue > 255 ? 255 : rValue
this.setData({ '_rgb.r': rValue })
},
changeG() {
let gValue = this.data._rgb.g + 5
gValue = gValue > 255 ? 255 : gValue
this.setData({ '_rgb.g': gValue })
},
changeB() {
let bValue = this.data._rgb.b + 5
bValue = bValue > 255 ? 255 : bValue
this.setData({ '_rgb.b': bValue })
}
}
})

  

八、组件的生命周期函数

全部的钩子函数

// components/rgbView/rgbView.js
Component({
lifetimes: {
// 创建完成后执行
created() {},
// 组件实例和页面完成dom绑定后执行,等同vue的mounted
attached() {},
// 组件再页面的视图渲染完成
ready() {},
// 组件被更新后执行(组件实例移动到节点树的新位置)
moved() {},
// 组件从页面的dom树中移除时触发
detached() {},
// 组件发生异常触发
error() {}
}
})

主要的三个函数

2.组件主要的生命周期函数
在小程序组件中,最重要的生命周期函数有3个,分别是created、attached、 detached。 它们各自的特点
如下:

① 组件实例刚被创建好的时候,
  created生命周期函数会被触发
● 此时还不能调 用setData
● 通常在这个生命周期函数中, 只应该用于给组件的this添加一些自定义的属性字段 ② 在组件完全初始化完毕、
  进入页面节点树后,attached 生命周期函数会被触发
  此时,this.data 已被初始化完毕
● 这个生命周期很有 用,绝大多数初始化的工作可以在这个时机进行( 例如发请求获取初始数据)

③ 在组件离开页面节点树后,detached生命周期函数会被触发
● 退出一个页面时,会触发页面内每个自定义组件的detached生命周期函数
● 此时适合做一些清理性质的工作

  

九、所属页面的生命周期函数

1.什么是组件所在页面的生命周期
有时,自定义组件的行为依赖于页面状态的变化,此时就需要用到组件所在页面的生命周期。

// components/rgbView/rgbView.js
Component({
pageLifetimes: {
// 所引用的页面被展示时执行
show() {},
// 所引用的页面被隐藏时执行
hide() {},
// 所引用的页面被尺寸变化时执行, 可以获取size大小
resize(size) {},
}
})

 

演示案例,在颜色组件中编写一个随机颜色生成的方法:

  /**
* 组件的方法列表
*/
methods: {
/**
* 生成随机色彩
*/
_randomColor() {
this.setData({
_rgb: {
r: Math.floor(Math.random() * 256),
g: Math.floor(Math.random() * 256),
b: Math.floor(Math.random() * 256)
}
})
},
}

  

在页面渲染展示的周期时刻调用:

  pageLifetimes: {
// 所引用的页面被展示时执行
show() {
// 在引用页面展示时触发
this._randomColor()
}
}

  

十、Slot 组件插槽

单个插槽

编写一个组件

<!--components/test4/test4.wxml-->
<text>components/test4/test4.wxml</text> <view>
<view>这是组件的内部结构</view>
<slot></slot>
</view>

使用组件:

<test4>
<text>这是嵌入组件插槽的部分</text>
</test4>

  

多个插槽

<view>
<view>这是组件的内部结构1</view>
<slot name="before"></slot>
<view>这是组件的内部结构2</view>
<slot name="after"></slot>
<view>这是组件的内部结构3</view>
</view>

微信新版本需要追加JS配置项:

黑马教程演示没有,说明在老版本可以直接配置

// components/test4/test4.js
Component({
options: {
// 开启多插槽支持
multipleSlots: true,
}
}

使用时需要指明名称:

<test4>
<text slot="before">这是嵌入组件插槽的部分1</text>
<text slot="after">这是嵌入组件插槽的部分2</text>
</test4>

  

十一、组件之间通信问题

1.父子组件之间通信的3种方式

①属性绑定
●用于父组件向子组件的指定属 性设置数据,仅能设置JSON兼容的数据 ②事件绑定
● 用于子组件向父组件传递数据,可以传递任意数据 ③获取组件实例
● 父组件 还可以通过this.selectComponent()获取子组件实例对象
● 这样就可以直 接访问子组件的任意数据和方法

  

一、父组件(页面) 向 子组件传递数据:

<father counter="{{val1}}" />
<view> father组件 counter值: {{val1}}</view>  

Father组件接参:

// components/father/father.js
Component({
/**
* 组件的属性列表
*/
properties: {
counter: {
type: Number
}
}
})

二、子组件向父组件传递数据

3.事件绑定
事件绑定用于实现子向父传值,可以传递任何类型的数据。使用步骤如下:

① 在父组件的js中,定义一个函数,这个函数即将通过自定义事件的形式,传递给子组件

② 在父组件的wxml中,通过自定义事件的形式,将步骤1中定义的函数引用,传递给子组件

③ 在子组件的js中,通过调用this.triggerEvent(自定义事件名称',{/*参数对象*/ }) ,将数据发送到父组件

④ 在父组件的js中,通过e.detail获取到子组件传递过来的数据

  

1、Father组件先追加事件和展示

<!--components/father/father.wxml-->
<text>components/father/father.wxml</text> <view>展示Father组件 counter值:{{counter}}</view>
<button bindtap="addCounter">+1</button>

JS代码,使用事件触发器配置事件和传递值:

  /**
* 组件的方法列表
*/
methods: {
addCounter() {
this.setData({ counter: this.properties.counter + 1})
// 给父组件进行同步
this.triggerEvent('sync', { value: this.properties.counter})
}
}

页面使用组件时,绑定对应的接收方法:

<father counter="{{val1}}" bind:sync="syncCounter" />
<view> father组件 counter值: {{val1}}</view>

方法编写:

  syncCounter(event) {
// 接收从子组件发送过来的参数
this.setData({ val1: event.detail.value })
},

  

三、直接获取组件实例实现调用

可在父组件里调用this.selectComponent("id或class选择器"),获取子组件的实例对象,

从而直接访问子组件的任意数据和方法。

调用时需要传入一-个选择器,例如this.selectComponent(".my-component")。

<father
counter="{{val1}}"
bind:sync="syncCounter"
class="cf"
id="componentFather" />
<view> father组件 counter值: {{val1}}</view>
<button bindtap="getComponentFather"> 测试</button>

JS代码:

现版本拿不到组件的方法,data属性可以获取

  /**
* 直接获取组件实例
*/
getComponentFather() {
// 或者id选择器 this.selectComponent('#componentFather')
// 或者类选择器 this.selectComponent('.cf')
const father = this.selectComponent('.cf')
console.log(father)
console.log(father.data.counter)
// 拿不到组件方法? 清空缓存,刷新页面再尝试
father.addCounter()
},

 

十二、behaviors

1.什么是behaviors
behaviors是小程序中,用于实现组件间代码共享的特性,类似于Vue.js中的"mixins"

2. behaviors的工作方式
每个behavior可以包含一组属性、 数据、生命周期函数和方法。

组件引用它时,它的属性、数据和方法会被合并到组件中。

每个组件可以引用多个behavior, behavior 也可以引用其它behavior。

3.创建behavior

调用Behavior(Object object)方法即可创建一一个共享 的behavior实例对象,供所有的组件使用:

// /behaviors/bhvirs1.js
module.exports = Behavior({
// 属性
properties: {},
// 数据
data: { msg: 'Hello Behaviors!'},
// 方法
methods: { }
})

  

4.导入并使用behavior

在组件中,使用require()方法导入需要的behavior,

挂载后即可访问behavior中的数据或方法,

示例代码如下:

// components/father/father.js
const b1 = require('../../behaviors/bhvirs1') Component({
behaviors: [b1],
})

  

组件可以展示Behaviors中的值

<view>展示Behvior数据 {{msg}}</view>

  

对应的所有设置属性:

冲突问题,见官方文档描述

https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/behaviors.html

  

【微信小程序】 自定义组件的更多相关文章

  1. 微信小程序自定义组件,提示组件

    微信小程序自定义组件,这里列举了一个常用的提示自定义组件,调用自定义组件中的方法和字段.仅供参考和学习. 编写组件: 在根目录下添加“components”目录,然后像添加Page页面一样添加自定义组 ...

  2. 微信小程序自定义组件

    要做自定义组件,我们先定一个小目标,比如说我们在小程序中实现一下 WEUI 中的弹窗组件,基本效果图如下. Step1 我们初始化一个小程序(本示例基础版本库为 1.7 ),删掉里面的示例代码,并新建 ...

  3. 微信小程序自定义组件的使用以及调用自定义组件中的方法

    在写小程序的时候,有时候页面的内容过多,逻辑比较复杂,如果全部都写在一个页面的话,会比较繁杂,代码可读性比较差,也不易于后期代码维护,这时候可以把里面某部分功能抽出来,单独封装为一个组件,也就是通常说 ...

  4. 微信小程序自定义组件-下拉框

    这个是网址https://www.cnblogs.com/zjjDaily/p/9548433.html 微信小程序之自定义select下拉选项框组件 知识点:组件,animation,获取当前点击元 ...

  5. 微信小程序自定义组件实现

    官方从 1.6.3 开始对于自定义组件这一块有了比较大的变动,首先比较明显的感觉就是文档比以前全多了,有木有!,现在小程序支持简洁的组件化编程,可以将页面内的功能模块抽象成自定义组件,以便在不同的页面 ...

  6. 微信小程序自定义组件封装及父子间组件传值

    首先在我们可以直接写到需要的 page 中,然后再进行抽取组件,自定义组件建议 wxzx-xxx 命名 官网地址:https://developers.weixin.qq.com/miniprogra ...

  7. 微信小程序 自定义组件(stepper)

    项目目录: 步骤一:创建组件 声明这一组文件为自定义组件 stepper.json { "component": true, "usingComponents" ...

  8. 微信小程序 自定义组件(modal) 引入组件

    项目结构: 步骤一:创建组件 声明这一组文件为自定义组件 modal.json { "component": true, // 自定义组件声明 "usingCompone ...

  9. 微信小程序 自定义组件 多列选择器 对象数组 ObjectArray 自关联 三级联动

    使用方法 在 Page.json 注册组件 { "usingComponents": { "address-picker": "/component/ ...

  10. 微信小程序自定义组件——接受外部传入的样式类

    https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/wxml-wxss.html 外部样式类 有时, ...

随机推荐

  1. umask永久修改用户创建文件权限

    Linux里永久设置用户创建文件权限的配置文件是/etc/profile.可以在该文件中添加umask命令来设置默认权限.具体操作步骤如下: 打开/etc/profile文件:sudo vi /etc ...

  2. Linux进程间通信-FIFO(命名管道)

    本系列文章主要是学习记录Linux下进程间通信的方式. 常用的进程间通信方式:管道.FIFO.消息队列.信号量以及共享存储. 参考文档:<UNIX环境高级编程(第三版)> 参考视频:Lin ...

  3. css3颜色模式 圆角的实现 width的属性值 触发怪异盒模型

    Css颜色模式: rgb(255,0,0) rgba(255,0,0,0.5)(0.5是透明度) hsl(58%,56%)色彩饱和度 hala() border-image   url(路径) 向内偏 ...

  4. Prometheus 监控平台组件深度讲解

    Prometheus 的重要性和流行度已经无需多言.直入主题,本文对 Prometheus 监控平台的各个组件做深度讲解,希望能帮助读者更好地理解 Prometheus. 监控系统的核心逻辑 对于一套 ...

  5. Cannot set properties of undefined (setting 'dataIndex')""

    前端写桑基图的时候碰到以上bug 原因是: 桑基图中的name值有重复的,把重复的name值去掉就好了

  6. 利用Wireshark抓包分析DNS域名解析过程

    一.DNS协议概述   DNS协议也可以称为DNS服务,全称是Domain Name System,即域名系统,和HTTP协议一样,也是一个位于应用层的协议(服务),它是基于运输层的UDP协议的.从D ...

  7. mysql自带test数据库表的默认属性:Collation latin1_swedish_ci 更新为utf8_general_ci,解决MYSQL数据库乱码

    ## mysql自带test数据库表的默认属性:Collation latin1_swedish_ci 更新为utf8_general_ci,解决MYSQL数据库乱码USE test;CREATE T ...

  8. Kotlin 编程语言详解:特点、应用领域及语法教程

    什么是 Kotlin? Kotlin 是一种现代.流行的编程语言,由 JetBrains 在 2016 年发布. 自发布以来,它已经变得非常流行,因为它与 Java 兼容(Java 是目前最流行的编程 ...

  9. python logging去掉selenium大量的日志

    问题 二次封装logging模块,设置级别为DEBUG,默认所有级别的日志都可以收集到:在发起ui自动化,打开浏览器输入网址,进行页面操作时,打印了大量的connectionpool.remote_c ...

  10. redhat6.5 升级 openssl

    上传版本包: openssl-1.0.1u.tar.gz 解压缩安装包: tar -xf openssl-1.0.1u.tar.gz 安装版本: ./config --prefix=/usr/loca ...