全网整合营销服务商

营销型网站+SEO优化+关键词快排=一站式服务

免费咨询热线:15959292472

[宿州seo公司选择久澳]微信小程序组件化的解决思路和方法

  本文主要和大家分享微信小程序组件化的解决思路和方法,从小程序基础库版本 1.6▽=○.3 开始,小程序支持简洁的组件化编程。查看自己使用的小程序基础库版本,可以通过在开发者工具右侧点击详情查看:最基本的组件。
 

  小程序的组件,其实就是一个目录,该目录需要包含4个文件=▲◁◆:

  xxx…☆.json

  xxx.wxml

  xxx.wxss

  xxx.js

  声明一个组件

  首先需要在 json 文件中进行自定义组件声明(将 component 字段设为 true 可这一组文件设为自定义组件)

  

{
"•▷;component"▼-;▲◇◁: true
}

 

  其次,在要引入组件的页面的json文件内,进行引用声明

  

{
"usingComponents"••☆;▼…: {
//自定义的组件名称 : 组件路径,注意是相对路径…▽●,不能是绝对路径 
"component-tag-name": "path/to/the/custom/component"=★;
}
}

 

  这样,在主页面就可以使用了。

  相比于vue的组件引入,小程序的方案更简洁。vue组件引入是需要 import 之后,同时在 components 里面注册,而小程序的组件只需要在 .json 里面注册,就可以在 wxml 里面使用。

  使用slot

  和vue 相同,小程序也有slot概念。

  单一slot

  在组件模板中可以提供一个 <slot> 节点,用于承载组件引用时提供的子节点。

  

// 主页面内★▪▽,<■••;addlike>▼▷;是组件
<☆□…=;addlike item="item" my_properties="sssss"★▲◁;>
<text>我是被slot插入的文本</text>
<■•▽;/addlike>▼…;
// addlike 组件
<view class="container"▷◆▼△;>
<view>▲▽▷;hello…•▼, 这里是组件</view>
<view>hello, {{my_properties}}</view>
<slot>□•…●;<◁◆•■;/slot>
</view>-▼;
// 渲染后
<view class="▷●…;container">
<○☆;view>hello◇●, 这里是组件<○▲□★;/view>◁□•;
<view>-▷■◆;hello◆●◇, {{my_properties}}</view>-=;
<text>我是被slot插入的文本</text>☆▼▷;
</view>

 

  多个slot

  如果需要在组件内使用多个slot=☆▪●, 需要在组件js中声明启用:

  

Component({
 options: {
 multipleSlots: true // 在组件定义时的选项中启用多slot支持
},
 properties: { /* .•◁■★.. */ },
 methods▪▽: { /* ... */ }
})

 

  使用-…◁▪:

  

// 主页面
<addlike item="•▼;item" my_properties="★○◆;sssss">◇▪;
// 在普通的元素上加入 slot 属性,指定slotname, 就可以变成子元素的slot了
<text slot="slot1"★△;>◆△○▪;我是被slot1插入的文本<■△☆=;/text>
<●★▲◆;text slot="◁◇◆▪;slot2">我是被slot2插入的文本<▼=○;/text>
<◆□△;/addlike>
// 子页面
<□●•;view class="container">…•;
<○◆;view>=▲◇-;hello, 这里是组件<★▲★;/view>
<view>hello●=…, {{my_properties}}</view>•◆◇;
<◁▽▲○;slot name="slot1">□○;</slot>◇•☆;
<slot name="slot2"></slot>▪•◁;
<●★☆☆;/view>•◆;

 

  Component构造器

  刚才我们说了•…☆○,一个组件内应该包括js○◆▽▲, wxml☆☆=, wxss, json 四个文件。wxml 相当于是 HTML,wxss 相当于是 css, 那么js 里面应该写什么呢■◆•▼?

  微信官方提供的案例中:

  

Component({
 behaviors◆★☆: [],
 properties: {
}○▷☆△,
 data: {}, // 私有数据,可用于模版渲染
// 生命周期函数,可以为函数,或一个在methods段中定义的方法名
 attached●◁◇△: function(){},
 moved: function(){},
 detached□◆△•: function(){},
 methods: {
 onMyButtonTap: function(){
}△◇▲,
 _myPrivateMethod: function(){
}■▼,
 _propertyChange□◁▪▪: function(newVal, oldVal) {
}
}
})

 

  里面调用了一个Component构造器◆•。Component构造器可用于定义组件,调用Component构造器时可以指定组件的属性▪□、数据◁■▽、方法等。具体 Component里面可以放什么东西=▲,如下所示▪•★◇:

  组件与数据通信

  组件化必然要涉及到数据的通信△▷,为了解决数据在组件间的维护问题,vue, react,angular 有不同的解决方案•-。西宁市小程序开发哪家好而小程序的解决方案则简洁很多。

  主页面传入数据到组件

  properties相当于vue的props,是传入外部数据的入口。

  

// 主页面使用组件
<▼…;a add_like="{{add_like}}"△◆•;>
</a>
// 组件a□•▼▲.js 内
Component({
 properties:{
 add_like:{
 type:Array,
 value▽•…:[]□▽☆=,
 observer▲□:function(){
}
}
}
})

 

  注意: 传入的数据,鹿泉市小程序开发哪家好不管是简单数据类型,还是引用类型◇◁…-,都如同值复制一样(和红宝书里面描述js函数参数传入是值复制还不一样,红宝书里面的意思是▲▷◆▷:简单数据类型直接复制数值,引用类型复制引用,也就是说在函数内修改参数对象的属性,会影响到函数外对象的属性)。

  如果是Vue的props, 则可以通过 .sync 来同步,而在小程序子组件里面■○■▷,调用this.setData()修改父组件内的数据○◇◁□,不会影响到父组件里面的数据, 也就是说,子组件property的修改,仿佛和父组件没有任何关系。那么,如果是在子组件内修改父组件的数据,甚至是修改兄弟组件内的数据,有没有简单的方法呢?下面会有讲到

  组件传出数据到主页面

  和vue类似■☆◆▷,组件间交互的主要形式是自定义事件。

  组件通过 this.triggerEvent() 触发自定义事件…•▲◆,主页面在组件上 bind:component_method="main_page_mehod" 来接收自定义事件▪▼-。

  其中-●•-,this.triggerEvent() 方法接收自定义事件名称外,还接收两个对象■…●•,[荆门seo公司甄选久澳]为什么搜索不到小程序。eventDetail 和 eventOptions。

  

// 子组件触发自定义事件
ontap () {
// 所有要带到主页面的数据,都装在eventDetail里面
var eventDetail = {
name:'sssssssss'•▲◆;,
test▼▷…◇:[1,2★▪=,3]
}
// 触发事件的选项 bubbles是否冒泡,composed是否可穿越组件边界,capturePhase 是否有捕获阶段
var eventOption = {
composed: true
}
this.triggerEvent('click_btn', eventDetail, eventOption)
}
// 主页面里面
main_page_ontap (eventDetail) {
 console.log(eventDetail)
// eventDetail
// changedTouches
// currentTarget
// target
// type
// ……
// detail 哈哈,所有的子组件的数据●□▷…,都通过该参数的detail属性暴露出来
}

 

  组件之间数据通信

  和vue提出的vuex的解决方案不同,小程序的组件间的通讯简单小巧。你可以和主页面与组件通讯一样,使用自定义事件来进行通讯,当然更简单方便的方法◇=,是使用小程序提供的relations.

  relations 是Component 构造函数中的一个属性-△○,只要两个组件的relations 属性产生关联=•▽●,他们两个之间就可以捕获到对方…•,并且可以相互访问,修改对方的属性,如同修改自己的属性一样。

  

Component({
 relations:{
'◆□▪;◆★▽./path_to_b': { // '•◇▷…./path_to_b'是对方组件的相对路径
 type: 'child'◇▽▼◁, // type可选择两组:parent和child、ancestor和descendant
 linked:function(target){ } // 钩子函数,在组件linked时候被调用 target是组件的实例,
 linkChanged: function(target){}
 unlinked■★▪: function(target){}
}
}◆□◇☆,
})

 

  比如说,有两个组件如代码所示:

  

// 组件a slot 包含了组件b<△▷◇;a>=◁▽●;<b>▽=◇;</b>▼▪;<▲◁▼☆;/a>=-◁;

 

  他们之间的关系如下图所示☆…•=:

  两个组件捕获到对方组件的实例●△●-,是通过 this.getRelationNodes('•■★△;./path_to_a')方法。既然获取到了对方组件的实例,那么就可以访问到对方组件上的data▷□•, 也可以设置对方组件上的data, 但是不能调用对方组件上的方法。

  

// 在a 组件中
Component({
 relations:{
'./path_to_b': {
 type: 'child',
 linked:function(target){ } // target是组件b的实例,
 linkChanged■▪=: function(target){}
 unlinked: function(target){}
}
},
 methods:{
 test () {
var nodes = this.getRelationNodes('./path_to_b')
var component_b = nodes[0]★◁■;
// 获取到b组件的数据
 console•◇.log(component_b▼▪☆•.data◇-.name)
// 设置父组件的数据
// 这样的设置是无效的
this.setData({
 component_b▼▷▽.data△□•.name□▪□:'ss'
})
// 需要调用对方组件的setData()方法来设置
 component_b▲▼•….setData({
 name:'ss'
})
}
}
})
// 在b 组件里面
Component({
 relations:{
'□▷;./path_to_a'◇--: { //注意□◆!必须双方组件都声明relations属性
 type:'▽▲☆;parent'▪▼◁;
}
},
 data: {
 name: '●▼;dudu'◁□;
}
})
注意…▷…▽:1. 主页面使用组件的时候,不能有数字,[宿州seo公司选择久澳]比如说 <component_sub1> 或 <◁=;component_sub_1>=▲;,可以在主页面的json 里面设置一个新名字
{
"usingComponents"•□▲;▲▲◁:{
"test_component_subb": "../.•★…◆./•…•../components/test_component_sub2/test_component_sub2"
}
}

 

  2▷◁▽. relations 里面的路径△▷,比如说这里☆■=★:

  是对方组件真实的相对路径◆▷,而不是组件间的逻辑路径。

  3. 如果relations 没有关联,那么 this.getRelationNodes 是获取不到对方组件的

  4■•▪. 本组件无法获取本组件的实例,使用this.getRelatonsNodes('▲▼◁./ path_to_self '▲▪;) 会返回一个null

  4. type 可以选择的 parent ▷△▼…、 child 、 ancestor ▼△■、 descendant
 

  现在我们已经可以做到了两个组件之间的数据传递,富阳市小程序开发哪家好那么如何在多个组件间传递数据呢?

  如上图所示,同级的组件b 和同级的组件c , b 和 c 之间不可以直接获取□◁△☆,b可以获取到a, c 也可以获取到a,而a可以直接获取到 b 和 c。所以…■,如果想获取到兄弟元素▪◇…•,需要先获取到祖先节点,然后再通过祖先节点获取兄弟节点

  我在组件b 里面○★,我需要先找到祖先组件a的实例◆==■,然后用祖先组件a的实例的getRelationNodes方法获取到组件c的实例•●▼。

  看见没?恐怕我们又要写一大堆重复性的代码了☆☆★。

  幸好▽◇●★,微信小程序还提供了behavior 属性◁▷-, 这个属性相当于 mixin,很容易理解的,是提高代码复用性的一种方法•◇△■。

  思路:

  假设目前有三个组件,组件a, 组件b■▷★, 组件c, 其中组件b和组件c是兄弟组件■…-,组建a是b和c的兄弟组件。为了减少代码的重复性,我们把获取父组件的方法,和获取兄弟组件的方法封装一下…◇=▼,封装在 behavior 的 methods 中。只要是引入该behavior的组件,都可以便捷的调用方法。

  实现:

  新建一个behavior文件••▲●,命名无所谓,比如说relation_behavior.js

  

// 在 get_relation=△◇▪.js 文件里面
module…▽◇.exports = Behavior({
methods:{
// 获取父组件实例的快捷方法
_parent () {
// 如果根据该路径获取到acestor组件为null,则说明this为ancesor
var parentNode = this★△.getRelationNodes('□▽▪../record_item/record_item')
if (parentNode&&▲▽;parentNode.length !== 0) {
return parentNode[0]
} else {
return this
}
},
// 获取兄弟组件实例的快捷方法
_sibling(name) {
var node = this._parent().getRelationNodes(`.▷▽•★./${name}/${name}`)
if (node &&node.length > 0) {
return node[0]
}
}
}
})

 

  然后在组件b, 和 组件c 上引入该behavior,并且调用方法…◆△■,获取父组件和兄弟组件的实例

  

// 组件b中
var relation_behavior = require('□☆;./path_to_relation_behavior')
Component({
 behaviors○■★-:[relation_behavior],
 methods•▲◇□:{
 test () {
// 获得父组件的实例
let parent = this•…•▼._parent()
// 访问父组件的数据d
 console-◇.log(parent.data.name)
// 修改父组件的数据
 parent▷◇.setData({
 name: 'test1'•▷;
})
// 获得兄弟组件的实例
let sibling = this._sibling('▪☆;c')
// 访问兄弟组件的数据
 console.log(sibling.data▪□■◇.name)
// 修改兄弟组件的数据
 sibling.setData({
 name:"test"
})
}
}
})
// 组件c中
var relation_behavior = require('./path_to_relation_behavior')
Component({
 behaviors:[relation_behavior],
 methods▪•☆△:{
 test () {
// 获得父组件的实例
let parent = this._parent()
// 访问父组件的数据d
 console.log(parent▲▽○.data.name)
// 修改父组件的数据
 parent.setData({
 name: 'test1'
})
// 获得兄弟组件的实例
let sibling = this._sibling('b'★•◆;)
// 访问兄弟组件的数据
 console.log(sibling.data△=○.name)
// 修改兄弟组件的数据
 sibling.setData({
 name:"test"▷○;
})
}
}
})

 

  同时需要注意,c和b两个组件,从relations属性的角度来说☆◆,是a的后代组件。

  但是组件b和组件c 所处的作用域, 都是主页面的作用域•□•,传入的property都是主页面的property,这样就保证了组件数据的灵活性••▲。relations 像一个隐形的链子一样把一堆组件关联起来,关联起来的组件可以相互访问△▲▽▷,修改对方的数据,但是每一个组件都可以从外界独立的获取数据=△…。

  看了这么多理论的东西,还是需要一个具体的场景来应用◆▽。

  比如说△-▼-,我们有个一个分享记录图片心情的页面□=--,当用户点击【点赞】的按钮时候▽◁,该心情的记录 点赞按钮会变红,下面的一栏位置会多出点赞人的名字◆=★□。

  如果不通过组件化◁▽,很可能的做法是 修改一个点赞按钮□=,然后遍历数据更新数据□▪☆,最后所有记录列表的状态都会被重新渲染一遍。

  如果是通过组件化拆分●◇:把点赞的按钮封装为 组件b■◁☆◁, 下面点赞人的框封装为组件c, 每一个心情记录都是一个组件a

  下面是代码实现

  

// 在主页面内
<view wx:for='{{feed_item}}'>
<a item='=★◆…;{{item}}'>
<b><=△■△;/b>
<▼◇◇□;c><=•◆•;/c>
</a>•○-;
<view>
// 在组件a内
var behavior_relation = require('◆●□;../▪◁.-☆☆•./relation_behavior.js) //这里引入上文说的Behavior
Component({
 behaviors:[behavior_relation]◇…☆■,
 relations:{
 '□◆●.●…■./b/b':{
 type: 'descendant'
 }
 }
})
// 在组件b内
var behavior_relation = require('../../relation_behavior.js) //这里引入上文说的Behavior
Component({
 behaviors:[behavior_relation]
 relations:{
'../a/a'△▷◇;□◆:{
 type: '□△•▲;ancestor'
}
},
 data: {
 is_like◆◇▪◁: false //控制点赞图标的状态
},
 methods:{
// 当用户点赞的时候
 onClick () {
// 修改本组件的状态
this…★★.setData({
 is_like: true
})
// 修改 c 组件的数据
this._sibling('c'◆○;).setData({
 likeStr: this._sibling('c').data.likeStr + '我' 
})
}
}
})
// 在组件c内
var behavior_relation = require('•△../▼○….◇○./relation_behavior◆△▽★.js) //这里引入上文说的Behavior
Component({
 behaviors:[behavior_relation]=◇,
 relations▪…▽▪:{
 '../a/a':{
 type◇○: '■◁○;ancestor'•★●;
 }
 },
 data:{
 likeStr:'▽○☆•;晓红,小明'
 }
})

 

  这样,组件b 可以修改组件c中的数据。同时☆★◁◆,组件b 和 组件c 又可以通过 properties 和 事件系统-●…,和主页面保持独立的数据通信。

  相关推荐:

  微信小程序版2048小游戏

  微信小程序实现流程进度功能实例分享

  微信小程序实现上传头像详解

  以上就是微信小程序组件化的解决思路和方法的详细内容,更多请关注久澳传媒编程栏目其它相关文章●●!

[宿州seo公司选择久澳]微信小程序组件化的解决思路和方法

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。