H5W3
当前位置:H5W3 > 其他技术问题 > 正文

小程序的超级组件(一),item组件

queryui是我们在项目中沉淀的小程序组件库,汲取了jquery的一些特性,使小程序更易于开发(微信原生)

github

小程序demo

queryui中ui-item/ui-list/ui-tree这三个非常重要的组件,我们称之为超级组件,超级组件依据标准化的数据,产出标准化的结构,赋予其样式形成不同的组件,queryui的绝大部分组件均由超级组件构成。

超级组件ITEM

item组件为组件的最小单位

wxml

<ui-item item="{{config}}" />
 

js

Pager({
data: {
config: {
id: '',
...
}
}
})
 

属性

下列说明
‘S’代表String
‘A’代表Array
‘O’代表Object
‘F’代表Function
‘b’代表bind
‘c’代表catch

名称 类型 说明
id S 容器id
$$id S 实例名称
title S/O/A 标题
type O 标题
img S/O/A 定义图片
itemClass S 样式类
itemStyle S 内联样式
attr O data-*属性
body A 子容器
footer A 子容器
dot A 特殊子容器
methods O 实例属性方法
tap S/F b:tap
aim S/F c:tap
longtap S/F longtap
longpress S/F longpress
touchstart S/F touchstart
touchmove S/F touchmove
touchend S/F touchend
catchlongtap S/F c:tap
catchlongpress S/F c:longpress

API

名称 说明
show 显示
hide 隐藏
toggle 切换显示隐藏
getData 当前数据
attr 当前data-*数据
mount 绑定id实例
parent 查找父级
siblings 查找兄弟
addClass 追加样式类
hasClass 是否有样式类
removeClass 删除样式类
toggleClass 切换样式类
css 设置内联样式
update 设置内联样式
reset 恢复初始值
find 查找子元素
hooks 钩子方法

使用说明

methods的__ready方法

method用于定义item组件的内部方法,__ready方法比较特殊,会在组件mounted后自动执行

config = {
title: '标题',
methods: {
__ready(){
console.log('===== 0000')
}
}
}
 

事件穿透

item组件在queryui中是最小组件,经常被作为子组件使用,组件层次有时候会非常深,queryui的内核会将深层item组件的事件方法一层一层透传到page层,可在父级拦截事件,如果不设拦截方法则page层设置的方法将响应事件

借用react-fiber的图片,在queryui中父子之间的关系也是如图所示

在queryui中,我们使用Pager替代Page来使用,Pager方法是Page的封装,使用方法完全一致,但包含了queryui组件的上下文环境

config = {  // 第一层
title: '标题',
body: [  // 第二层
{title: [ // 第三层
{$$id: 'three-level-item', title: '第三层item组件', aim: 'onTap'},
{$$id: 'three-level-item', title: '第三层item组件', aim: 'myTap'}
]}
],
methods: {
myTap(){
// 父级劫持了其子组件方法
}
}
}
Pager({
data: {
config: config
},
onTap(){
// 子组件方法被透传到page层中
}
})
 

自定义排序

配置支持图文排序,通过指定属性的顺序渲染结构,如下例

{title, img}
{img, title}
 

上述将渲染为文-图、图-文两种不同的结构

// 复杂一点,更多属性  
{img, body, title, footer},
{body, img, footer, title}
 

最终渲染结构顺序,取决于属性在定义时的位置顺序

parent(param)

当item作为子集时可用,这里的父级必须是queryui的组件而不是原生组件
一个参数,String类型,可为空,为空时表示直接父级,当指定param时,会自动向上找寻样式类名为param的父级

siblings(param)

当item作为子集时可用,这里的父级必须是queryui的组件而不是原生组件
一个参数,String类型,可为空,为空时表示返回所有兄弟对象,当指定param时,会在已查找到的兄弟中匹配样式类为param的兄弟

addClass(param)

一个参数,String类型,添加样式类,可同时添加多个样式类,使用空格区隔

removeClass(param)

一个参数,String类型,移除样式类,可同时删除多个样式类,使用空格区隔

toggleClass(param)

一个参数,String类型,切换样式类,支持同时切换多个样式类,使用空格区隔

css(param)

一个参数,String类型,设置item容器的内联样式

update(param, cb)

两个参数,param为Object类型,cb为Function类型,直接更新item属性,queryui内部使用setData来更新

hooks

作为item实例的钩子方法集合,本事是一个实例,具有一下api方法

数据部分

  1. setItem
    存储数据到key

  2. getItem
    取得key的数据

  3. append
    为key数据追加数据

  4. delete
    删除key数据

  5. getInfo
    获取说有数据存储的对象

方法部分

  1. on
    挂载方法到key,类似于jquery的on方法

  2. one
    挂载方法到key,只能被执行一次,之后被删除

  3. once
    挂载方法到key,该key有且只有一个挂载的方法,取决于最后挂载的方法

  4. off
    取消挂载在key上的方法,允许指定取消非匿名函数方法

  5. emit
    执行挂载到key的所有方法

  6. fire
    执行挂载到key的所有方法,之后清除所有该key下挂载的方法

  7. clear
    清空所有数据,方法,key

配置实例

定义查找实例id,容器id

config = {
$$id: 'uniq-id',
id: 'container-id' //作为view容器的id
}
onReady(){
let $inst = this.getElementsById('uniq-id')
console.log($inst)
}
 

下面demo实例中直接使用$inst表示为item组件的实例名

定义查找作为子集的item实例-1

config = {
$$id: 'father-uniq-id',
title: '标题',
body: [
{$$id: 'sub-uniq-id', title: '子标题'}
]
}
onReady(){
let $subinst = this.getElementsById('sub-uniq-id')
console.log($subinst)
}
 

定义查找作为子集的item实例-2

config = {
$$id: 'father-uniq-id',
title: '标题',
body: [
{$$id: 'sub-uniq-id', title: '子标题', itemClass: 'sub-class-name'}
]
}
onReady(){
let $inst = this.getElementsById('father-uniq-id')
let $sub = $inst.find('.sub-class-name')
}
 

定义查找作为子集的item实例-3

config = {
$$id: 'father-uniq-id',
title: '标题',
body: [
{$$id: 'sub-uniq-id',id: 'xxx', title: '子标题', itemClass: 'sub-class-name'}
]
}
onReady(){
let $inst = this.getElementsById('father-uniq-id')
$inst.children.forEach(item=>{
let itemData = item.getData()
if (itemData.id === 'xxx') {
console.log(item)
}
})
}
 

type定义容器类型

通过设置type,item可以将容器类型定义为view和scroll-view两种类型
暂时type只支持定义scroll-view类型,其他类型view容器暂不支持

config = {
type: {
'is': 'scroll',
'scroll-y': true
... // 其他scroll-view的属性
}
}
 

自定义item标题

config = {
title: '标题'
}
 

定制item

config = {
title: '标题',
itemClass: '',  // 指定item(view容器)的样式类
itemStyle: '',  // 设置item(view容器)的内联样式
attr: {...}    // 定义data-*属性,注意只有id会真实设置,其他属性通过attr方法获取
}
 

标题组

config = {
title: [
'标题-1',
'标题-2'
]
}
 

定制标题组

title为数组时,每一个数组项都将会以item子组件生成

config = {
itemClass: 'father-class-name',
title: [
{title: '子标题-1', itemClass: 'sub-class-name-1'},
{title: '子标题-2', itemClass: 'sub-class-name-2'},
]
}
 

itemClass等属性均被设置在所在的item子组件上

实例定义标题

$inst.update({
title: '新标题'
})
 

定义事件方法

config = {
title: '标题',
tap(e, param, inst){  // tap=bind:tap, aim=catch:tap, 其他事件方法与官方一致  
// param 在这里没有用到
console.log(inst)  // inst为item组件本身实例
}
}
 

使用methods定义事件方法

config = {
title: '标题',
tap: 'onTap?id=xxx&name=yyy',
methods: {
onTap(e, param, inst){
console.log(param)  // {id: 'xxx', name: 'yyy'}
console.log(inst)  // 为item实例本身
}
}
}
 

图片

config = {
img: 'path/to/your/img'
}
 

定制图片

config = {
img: {
src: 'path/to/your/img',
itemClass: '',  // 图片样式
itemStyle: '',  // 图片内联样式
mode: '',
webp: false,
'show-menu-by-longpress': false,
bindload: '',
...  // 官方属性
}
}
 

图片组

config = {
img: [
{src: 'http://www.abc.com/index.jpeg', itemClass: 'img-class', ...},
{src: 'http://www.abc.com/index.jpeg', itemClass: 'img-class', ...},
{src: 'http://www.abc.com/index.jpeg', itemClass: 'img-class', ...},
]
}
 

图-文

图片排序文字上面

config = {
img: {src: 'http://www.abc.com/index.jpeg', '...'},
title: '新标题'
}
 

文-图

文字排序图片之上

config={
title: '新标题',
img: {src: 'http://www.abc.com/index.jpeg', '...'}
}
 

标题-图组

let src = {src: 'http://www.abc.com/index.jpeg', '...'}
config = {
title: {title: '漂亮的手机图片', itemClass: 'caption'},
img: [src, src, src],
itemClass: 'item-tis'
}
 

图组-标题

let src = {src: 'http://www.abc.com/index.jpeg', '...'}
config = {
img: [src, src, src],
itemClass: 'item-tis',
title: {title: '漂亮的手机图片', itemClass: 'caption'},
}
 

制作一个简单的加载按钮

methods属性的使用

config = {
title: '点我loading',
tap: 'tapme',
itemClass: '.item-btn',
methods: {
tapme(e, param, inst){
if (!inst.hasClass('loading')) {
inst.update({title: '隐藏loading'})
} else {
inst.update({title: '点我loading'})
}
inst.toggleClass('loading')
}
}
}
 

加载按钮简化版

直接定义tap, aim(catchtap)方法

config = {
title: '点我loading',
itemClass: '.item-btn',
tap(e, param, inst){
if (!inst.hasClass('loading')) {
inst.update({title: '隐藏loading'})
} else {
inst.update({title: '点我loading'})
}
inst.toggleClass('loading')
}
}
 

使用body属性制作一个简单下拉框

使用body属性为item组件增加一组下拉菜单
该例中使用siblings方法操作兄弟集合

body属性类型为数组(Array)类型,该数组由item组件构成,且被包裹在className为hbody的view容器中,可以支持丰富的结构

config = {
title: '简单下拉框',
aim: 'tapdd',  //弹开、关闭下拉菜单
body: [
{title: '下拉选项一', aim: 'tapop?bodyIndex=1'}, // 选中项
{title: '下拉选项二', aim: 'tapop?bodyIndex=2'},
{title: '下拉选项三', aim: 'tapop?bodyIndex=3'},
],
itemClass: 'item-dropdown',
methods: {
tapdd(e, param, inst){
inst.toggleClass('active')
},
tapop(e, param, inst){
Pager.alert('选择了:'+param.bodyIndex.toString())
inst.siblings().removeClass('selected') // 兄弟元素去除选中样式
inst.addClass('selected') // 当前元素增加选中样式
setTimeout(() => {
this.toggleClass('active')
}, 3000);
}
}
}
 

使用dot属性添加小红点

使用dot属性为item组件添加小红点

dot属性类型为数组(Array)类型,该数组由item组件构成,支持丰富的结构,dot属性与body和footer属性不同在于,dot的子元素没有包裹容器,item容器作为其第一级父级,当父级容器属性position:relative时,子元素可以在父级中随意定位

config = {
title: '♻︎',
itemClass: 'item-reddot'  // 父级样式类
dot: [
{ title: 99, itemClass: 'reddot'} // 父级为item-reddot
],
}
 

update更新内容

使用update实例方法更新item组件的内容

onReady(){
$inst.udpate({
title: '新的标题'
})
$inst.udpate({
img: 'a image path'
})
$inst.udpate({
body: [ ... ]
})
}
 

reset重置内容

使用实例方法reset使被修改过的当前实例恢复到修改之前的数据及状态

onReady(){
$inst.reset()
}
 

使用实例钩子(hooks)

组件间交互,可以通过钩子来触发更改状态,hooks必须在有实例的状态下定义
wxml

<ui-item item="{config1}" />
<ui-item item="{config2}" />
 

js

config1 = { $$id: 'id-1' }
config2 = { $$id: 'id-2', tap: 'onTap' }
Pager({
onTap(e, param, inst){
// param和inst由queryui内部传递
// 这里的inst === $inst2
// 参数option为key-name方法的参数,
// 参数context为key-name方法的上下文
$inst1.emit('key-name', option, context)
},
onReady(){
const $inst1 = this.getElementsById('id-1')
const $inst2 = this.getElementsById('id-2')
$inst1.hooks.on('key-name', function(option){
$inst1.update({title: '新标题'})
})
}
})
 

本文地址:H5W3 » 小程序的超级组件(一),item组件

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址