微信小程序自定义组件

ps 由于作业部落貌似出了点问题,耽误了点时间,找了一个stackedit.io准备写。无奈,这是要自己建编辑器的节奏啊。没有一个能靠的注

为何存在组件

组件间的关系

使用relations实现组件的关系,即父子关系。

定义和使用组件间的关系

有时需要使用如下的组件间的关系

 <custom-ul> <custom-li> item1 </ custom-li> <custom-li> item2 </ custom-li>
</ custom-ul>

在上方中,
两个<custom-ul>以及<custom-li>两个组件都为自定义组件,如果进行通信会非常的难以操作,至此通过relations完成子父组件的定义,简化通信。
同样的以上方的栗子作为举例。

继续上一个栗子,新建一个页面,在新的页面中使用组件间的关系。

由于同属于一个custom大组件,所以直接在components中新建一个custom文件夹,表示一个大的新组件
由于其拥有一个子组件,所以再新建一个li文件夹,表示custom-li
目录如下

菜鸟一枚,设置的不一定正确。也不一定是最正统的,只是感觉。╮(╯▽╰)╭

设置custom/custom.js文件的relations的值

// components/custom/custom.js
Component({relations: {'./li/li' : {type: 'child',  // 设置关联的目标节点为子节点}}
})

接着设置祖先节点,即设置custom/li/li.js文件的内容

// components/custom/li/li.js
Component({relations: {'../../custom': {type: 'parent'  // 应为祖先节点}}
})

设置组件的wxml文件

<! - 组件/自定义/立/ li.wxml  - >
< view > components / custom / li / li.wxml </ view > < slot />
<!--components/custom/custom.wxml-->
<view>components/custom/custom.wxml</view>
<slot/>

接着设置page页面的wxml页面

<!--pages/ming/ming.wxml-->
<text>hello world</text>
<custom-ul><custom-li></custom-li><custom-li></custom-li><custom-li></custom-li><custom-li></custom-li>
</custom-ul>

至此完成。

关联一类组件

被微信的路径折腾的不轻,好吧,无奈,决定重新写

微信路径

微信路径太坑了。
理所应当应该是

/ 根目录
../ 父级目录
./ 当前目录

结果非要

../../

至今也没搞清楚路径是这么回事。算了,决定在同一个目录下完成模块的问题,不在另外的分一个模块的文件夹了。

总说

要形成的在page下的结构如下

<custom-form><view>input<custom-input></custom-input></view><custom-submit>shubmit</custom-submit>
</custom-form>

创建目录

创建目录如下

好啦,目录如上

这一次放弃将模块放在另外一个文件夹,这一场所有的和组件相关的内容都放在同一个文件夹下 。符合组件的精神

其中form表明该为一个form的组件。module表明组件的内容,其中module下还有一个behaviors表明是behaviors的内容的模块,input和submit表明是其子组件。

behaviors

书写behaviors的内容。

// components/form/module/behaviors/controlsmodule.exports = Behavior({// ...})

父组件

书写父组件及form的内容

// components/form/form.jsvar formControls = require('./module/behaviors/controls.js')Component({relations: {'formControls': {type: 'descendant', // 关联目标的节点应为子孙节点target: formControls // 所有设置behavior的组件的节点都为其子孙节点}}})

继续书写wxml的内容,其实就是添加一个挂载点的问题。

<!--components/form/form.wxml--><text>components/form/form.wxml</text><slot/>

input组件

// components/form/input/input.jsvar formControls = require('../module/behaviors/controls.js')Component({behaviors: [formControls],relations: {'../form': {type: 'ancestor', // 关联的目标节点应为祖先节点}}})

wxml

<!--components/form/input/input.wxml--><text>components/form/input/input.wxml</text><slot/>

submit组件

此为from的子组件

// components/form/submit/submit.jsvar formControls = require('../module/behaviors/controls.js')Component({behaviors: [formControls],relations: {'../form': {type: 'ancestor', // 关联的目标节点应为祖先节点s}}})

继续写wxml加上一个

<!--components/form/submit/submit.wxml--><text>components/form/submit/submit.wxml</text><label><slot/></label>

json配置文件

{"usingComponents": {"component": "/components/component","body": "/components/body/body","custom-form": "/components/form/form","custom-input": "/components/form/input/input","custom-submit": "/components/form/submit/submit"}}

编写页面的wxml

<custom-form><view><custom-input/></view><custom-submit/></custom-form>

完成(o)/
至此,根据一个behaviors完成一个组件

抽象性节点

抽象节点类似于挂载点,但是和挂载点不同的是,可以通过属性来更改挂载的组件。需要注意的一点是,其值需要为静态值,不能为动态值,抽象节点只能使用静态的内容。

但是个人感觉和挂载点还是有一点类似的作用,不过这个是通过不同的条件达到调用的目的。

抽象节点核心在于调用的时候才能确定内部需要什么组件,只有调用才能确认需要的组件,核心在于将业务和逻辑分离,彻底达到消除耦合的目的。

组件的目的在于尽可能的减少业务逻辑在里面。
注意,组件的确是要尽可能的减少逻辑在里面,因为组件的核心在于复用,在于大量的复用。减少重复代码的书写,即将一段业务中的重复的,多次的抽象出来,提取成为一个组件,如果因为某些原因,必须要存在一定的业务逻辑在里面,这个时候就需要抽象节点。

抽象节点和挂载点的不同就在上方体现出来了,抽象节点是必须有的,但是挂载点可有可无

抽象节点的核心在于分离,抽象。
再次感受抽象的重要性

在组件中使用抽象节点

在自定义模板中的一些节点,其对应的自定义组件不是由自定义组件本身确定的,由调用者确定,称为抽象节点

这定义╮(╯▽╰)╭

例如下面的代码

<view><label><selectable disabled="{{false}}"/></label>
</view>

在上方的代码中,selectable是由调用者确定的,需要在调用的时候根据属性值进行替换
还需要在json文件中添加如下的配置

{"componentGenerics": {"selectable": true}
}

直接声明该节点为抽象节点,其值由调用者确定

使用包含抽象节点的组件

上方是在代码中定义抽象节点。仅仅是定义,还不能使用。
如果要是使用抽象节点,需要再次添加属性

generic 为一个选项

在page页面中写入如下内容

<custom-form  generic:selectable="component"></custom-form>

表明引入一个组件,其中的抽象节点的selectable替换为component内容。

需要注意的是,需要在json文件中引入component的内容

默认组件

即在未指定组件内容的时候使用的组件
在组件文件夹中的json声明。
此时不需要使用true即可声明抽象节点

{"usingComponents": {},"componentGenerics": {"selectable": {"default": "/components/component"}}}

自定义组件扩展

自定义组件的扩展实质为提供了修改自定义组件定义段的能力。使用自定义组件的扩展能动态的修改的自定义组件的扩展。

一直别一个及其简单的问题困扰了很久,es6中新增加的对象属性声明,并赋值,可以直接省去function关键字。

关于es6

关于es6的问题,是滴,被微信官方文档的一个写法纠结了很久

```js
module.exports = Behavior({definitionFilter(defFields) {defFields.data.from = 'behavior'},
})

就上方的写法,由于是一种新的写法,上方的等价于下方的内容

module.exports = Behavior({definitionFilter: function definitionfilter(defFields) {defFields.data.form = 'behavior'}
})

仅仅是一种新的es6的写法。一种声明私有函数的方式,一般在组件里声明私有函数。这个时候,可以直接省去function。
好啦,最大的障碍解决了。

definitionfilter函数

Behavior()构造器定义了一个新的段,即definitionfilter段。
该函数具有两个定义段,分别是defFields以及 definitionFilterAll此为两个参数
下面解释这两个参数

defFields参数

对于该参数来说,是当前被调用使用的behavior,这个灰常简单不在多说

definitionFilterAll参数

这个参数为behaviors顺序。
使用一个官方的栗子来解释吧

// behavior3.js
module.exports = Behavior({definitionFilter(defFields, definitionFilterArr) {},
})// behavior2.js
module.exports = Behavior({behaviors: [require('behavior3.js')],definitionFilter(defFields, definitionFilterArr) {// definitionFilterArr[0](defFields)},
})// behavior1.js
module.exports = Behavior({behaviors: [require('behavior2.js')],definitionFilter(defFields, definitionFilterArr) {},
})// component.js
Component({behaviors: [require('behavior1.js')],
})

在上方的栗子中,每个defFelds都为当前调用的behaviors,而definitionFilterArr是这样的情况
当调用2的时候,因为会调用3的definitionFilter函数,对其内容进行更改,在3中的definitionFilter函数有两个参数,第一个参数为2的behavior的定义段,即2中的各项内容进行更改,第二个参数为3的behaviors的内容,由于3没有引用其他的behaviors,所以为一个空数组

总结,当调用的时候,第一个参数为调用者的behaviors,而第二个参数为其本身的behaviors

当进行到1的时候,将会调用2的definitionFilter,其2的该函数的第一个参数为1的behaviors,和其他的一些项,第二个参数为2引用的behaviors,由于2引用了3的behaviors,而3没有引用,所以是一个只有一项的数组,该数组的内容为2引用的behaviors,即3的definitionFilter定义段

如果当调用1的时候,要调用3的definitionFilter函数
分析,3的definitionFilter函数由2的behaviors函数调用,而2的·definitionFilter函数是由1的behaviors调用,并且3的definitionFilter函数在2中的definitionFilter函数的第二个参数的第一项(数组)中有其内容,所以需要在2中写数组,用来调用3的definitionFilter函数。
所以第2中有definitionFilterArr[0](defFields)表明是调用3的definitionFilter而参数defFields表明是2中的behaviors中的内容。

同理使用Component构造函数的时候,将会调用1的definitionFilter函数对Component内容进行更改。

最后,总结就是一句话

当调用的时候,第一个参数为调用者的behaviors,而第二个参数为其本身的behaviors

官方扩展包 https://github.com/wechat-miniprogram/computed 实现动态的计算属性

哦。貌似切图仔最重要的瀑布流还没有学习

第三方自定义组件

终于到自己的知识范畴啦。目前已经会node.js和npm,下面的就比较好学习了。
微信小程序的官方ide支持npm
官方提供有一个模板 https://github.com/wechat-miniprogram/miniprogram-custom-component
属于小程序的自定义脚手架的相关内容。
官方的事例的组件 https://github.com/wechat-miniprogram/slide-view
以及官方提供的命令行工具 https://github.com/wechat-miniprogram/miniprogram-cli

命令行工具

npm install -g @wechat-miniprogram/miniprogram-cli

东西有点多

安装完成以后进行初始化

miniprogram init [options] [dirPath]

进行选择即可。

miniprogram

即第三方的自定义组件,custom-component为创建一个空的自定义组件目录,miniprogram为一个小程序的自定义组件的快速的开始,会有一个从github上下的一个模板,写代码即可。
属于脚手架的一部分。

由于涉及到glup,暂时搁置。

目录如下

|--miniprogram_dev // 开发环境构建目录
|--miniprogram_dist // 生产环境构建目录
|--src // 源码
|   |--common // 通用 js 模块
|   |--components // 通用自定义组件
|   |--images // 图片资源
|   |--wxml // 通用 wxml 模版资源
|   |--wxs // 通用 wxs 资源
|   |--wxss // 通用 wxss 资源
|   |
|   |--xxx.js/xxx.wxml/xxx.json/xxx.wxss // 暴露的 js 模块/自定义组件入口文件
|
|--test // 测试用例
|--tools // 构建相关代码
|   |--demo // demo 小程序目录,开发环境下会被拷贝生成到 miniprogram_dev 目录中
|   |--test // 测试工具相关目录
|   |--config.js // 构建相关配置文件
|
|--gulpfile.js

即,按照上方进行构建相关的组件即可。目前src部分能看明白,暴露的接口和node.js的包如出一辙,都是直接在主文件中进行暴露出接口的,最上方两个文件,最开始接触到的是git的工作流,根据git的工作流也能明白,最后test和tools这一点还有点晕。测试用例使用下方的命令构建出测试用例。

npm run test

tools中的demo为一个演示,即开发者下载下来内容以后将会直接出现的内容,例如,文档中的使用微信小程序打开这一点就是参考这样的,
test测试工具相关目录,进行测试的工具存放的目录。例如进行自动化测试的一些脚本要书写在这里。
config.js为进行自动化构建所要进行的文件,

ps 由于构建工具未学,构建工具的学习重点肯定是配置文件的书写。以及对接口的暴露等。

至此,暂时结束微信小程序的自定义组件化,明天写插件。

微信小程序自定义组件(二)相关推荐

  1. 微信小程序--自定义组件(超详细 从新建到使用)

    微信小程序–自定义组件 微信小程序官网介绍! 本文提供给急需使用自定义组件人群,以下是博主个人理解和案例!可以辅助官网来看 介绍: 从小程序基础库版本 1.6.3 开始,小程序支持简洁的组件化编程.所 ...

  2. 微信小程序自定义组件-树形数据表格(进阶版)

    前言 一.下载引用 二.使用treegrid组件 三.使用文档 属性 事件 四.组件源码 利用递归思想编写的表格行--treegrid-treeline 树形表格--treegrid-treegrid ...

  3. 一步步教你实现微信小程序自定义组件

    一步步教你实现微信小程序自定义组件 更新时间:2022年03月21日 11:12:34   作者:naluduo233 之前做小程序开发的时候,对于开发来说比较头疼的莫过于自定义组件了,下面这篇文章主 ...

  4. 【小程序】一文学会微信小程序自定义组件封装

    一.什么是自定义组件 在实际开发过程中,经常会有代码复用的情况,即在不同的页面有类似结构的代码块,类似的代码反复出现,这样会增加代码维护成本,也会造成代码的高耦合,为了解决这一情况,微信小程序支持了更 ...

  5. 微信小程序自定义组件方案

    前言:小程序已于11月初开放了小程序组件功能,但事件方面还不是很完善,有的组件暂时可能还是要用其他方式来实现,这里简单记录下开发小程序自定义组件的要点. 在小程序官方开发组件开发功能之前,自定义组件的 ...

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

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

  7. 微信小程序自定义组件子传父详解(多图)

    微信小程序自定义组件子传父详解 前言: 刚开始为了测试父传子,所以把页面的数组放在了父组件中 1. 然而子组件中绑定的自定义点击事件依然放在子组件的js文件中 2. 所以就会出现我们点击页面的文字能改 ...

  8. 微信小程序自定义组件的基本使用

    微信小程序自定义组件的基本使用 组件与模块类似,实现了功能的复用,提高开发速率,减少代码量 在开发过程中 , 总会遇到一些功能板块是相同或很类似的 .如两个不同页面都有搜索框 , 或者 导航栏等 . ...

  9. 基于canvas 2D实现微信小程序自定义组件-环形进度条

    基于canvas 2D实现微信小程序自定义组件-环形进度条 最近开发一个小程序项目博闻金榜答题小程序,需要使用到一个可以显示答题倒计时的组件,基于进度条实现,下面就主要介绍基于canvas2D实现一个 ...

最新文章

  1. 基于MMSeg算法的中文分词类库
  2. 小程序当中的文件类型,组织结构,配置,知识点等
  3. 字符指针+结构体排序(后缀子串排序)
  4. 关于Visual Studio 2017安装需要注意的细节
  5. win10隐藏linux,Win10如何隐藏Windows Defender任务栏图标
  6. SQL Server 2005 Service Pack 2 – CTP December 2006发布
  7. maven学习笔记第一节一-maven install 模块之间相互引用
  8. alisql mysql5.7_wps2016抢鲜版_AliSQL 5.6.32 vs MySQL 5.7.15抢鲜测试-云栖社区-阿里云
  9. Ubuntu入门——基础终端命令
  10. 百度地图生成器不显示图片的原因
  11. [生存志] 第11节 历代大事件概览 春秋
  12. 甘超波:NLP五步觉察法
  13. 网站死链接检测工具 Xenu 汉化版
  14. CAD2015 C#二次开发 字体变形
  15. .Net Core学习笔记(二)MVC框架
  16. soundwire修改服务器,SoundWire Server,电脑声音实时同步到移动手机
  17. 用 zotero 管理文献和个人知识库
  18. 看医疗行业如何建立信息化战略决策
  19. 使用360极速(360Chrome双核)浏览器,360邮件通初始化失败的解决方法
  20. JZOJ8.14(C组)帕秋莉·诺雷姬

热门文章

  1. Python 正则模块的应用
  2. BIM新时代背景下的建筑业技术变革
  3. Linux下抓包工具tcpdump以及分析包的工具wireshark
  4. 【转载】一百年后,人类怎样编程?
  5. 周末之个人杂想(四)
  6. Alibaba Cloud Toolkit一键上云神器
  7. 【设计模式系列】行为型之策略模式
  8. arcgis xml 下载 切片_arcgis api 4.x for js地图加载arcgisserver本地离线瓦片(附源码下载)...
  9. yum 安装boost
  10. sqlserver 只有函数和扩展存储过程才能从函数内部执行