likes
comments
collection
share

微信小程序之behaviors

作者站长头像
站长
· 阅读数 54

概括

一句话总结: behaviors是用于组件间代码共享的特性, 类似一些编程语言中的'mixin'或者'traits'.

A.每个behaviors包含一组属性、数据、生命周期函数、自定义方法 -> 组件引用它时, 属性、数据、生命周期函数、自定义方法都会被合并到组件中,生命周期函数也会在对应的时机被调用. B. 每个组件可以引用多个behavior, behavior也可引用其它behavior;

Demo演示

下文主要贴出了主要代码, 可自行拷贝运行.

// 新建page, 页面级wxml
<test-comp></test-comp>
// 页面级json
{
  "usingComponents": {
    "test-comp": "../components/testComp/testComp"
  }
}
// 新建个组件, 组件级wxml
<view>属性: {{myBehaviorProperty}} --- {{myCompProperty}}</view>
<view>数据: {{myBehaviorData}} --- {{myCompData}}</view>
<view bind:tap="myBehaviorMethod">触发behavior的自定义方法</view>
<view bind:tap="myCompMethod">触发组件的自定义方法</view>

// 组件级js
import testBehavior from './testBehavior'
Component({
  behaviors: [testBehavior],
  properties: {
    myCompProperty: {
      type: String,
      value: ''
    }
  },
  data: {
    myCompData: 'myCompData'
  },
  created: function (){
    console.log('[my-component]- created')
  },
  attached: function (){
    console.log('[my-component]- attached')
  },
  ready: function (){
    console.log('[my-component]- ready')
  },
  methods: {
    myCompMethod: function () {
      console.log('[my-component]- method')
    }
  }
})
// behavior级
export default Behavior({
  behaviors: [],
  properties: {
    myBehaviorProperty: {
      type: String,
      value:  'myBehaviorProperty'
    }
  },
  data: {
    myBehaviorData: 'myBehaviorData'
  },
  created: function () {
    console.log('[my-behavior]- created')
  },
  attached: function () {
    console.log('[my-behavior]- attached')
  },
  ready: function () {
    console.log('[my-behavior]- ready')
  },
  methods: {
    myBehaviorMethod: function () {
      console.log('[my-behavior]- method')
    }
  }
})

先来对上述代码做一波解析: behavior结构: 属性: myBehaviorProperty 数据: myBehaviorData 生命周期: created() && attached() && ready() 自定义方法: myBehaviorMethod

组件引入该behaviors后的结构: 属性: myBehaviorProperty、 myCompProperty 数据: myBehaviorData、myCompData 生命周期: created() && attached() && ready() 自定义方法: myBehaviorMethod、myCompMethod

紧接着, 来看看代码运行结果: 也许你会对输出有疑问, 先不着急, 慢慢往下看. 微信小程序之behaviors

进阶演示

上面的Demo仅演示了最基础的behaviors的用法, 接下来我们看看遇到同名的属性or数据or生命周期方法or自定义方法, 该属性会做些什么呢? 1. 若具有同名的属性或方法 A. 若组件本身有, 则组件会覆盖behavior; B. 若存在嵌套子behaviors的情况, 则父behavior会覆盖子behavior;

Demo演示: 基于上面的Demo代码, 追加如下部分

// 新建个组件, 组件级wxml
<view bind:tap="sameMethod">同名属性: {{sameProperty}}</view>

// 组件级js
properties: {
  sameProperty: {
    type: String,
    value: 'sameProperty-myCompProperty'
  }
},
methods: {
  sameMethod: function (){
    console.log('[my-component]- sameMethod')
  }
}

// behavior级
properties: {
   sameProperty: {
     type: String,
     value: 'sameProperty-myBehaviorProperty'
   }
},
methods: {
  sameMethod: function (){
    console.log('[my-behavior]- sameMethod')
  }
}

上述代码表现形式如下: 组件的同名属性覆盖了behavior的同名属性; 点击自定义方法, 触发的是组件的自定义方法. 微信小程序之behaviors 至此, 你会不会好奇如果属性是个object, 是怎么个表现形式呢, 接下来看看实际效果.

// 新建个组件, 组件级wxml
<view>同名属性: {{sameProperty && sameProperty.val1}}</view>
<view>同名属性: {{sameProperty && sameProperty.val2}}</view>


// 组件级js
properties: {
  sameProperty: {
    type: Object,
    value: {
      val1: '[my-component]-同名属性类型是对象'
    }
  }
}

// behavior级
properties: {
  sameProperty: {
    type: Object,
    value: {
      val1: '[my-behavior]-同名属性类型是对象',
      val2: '[my-behavior]-体现同名对象类型不会做合并'
    }
  }
}

上述代码表现形式如下: 同名属性即使是对象类型, 也只会做覆盖, 区别于下文的同名数据的合并操作哦. 微信小程序之behaviors

2. 若有同名的数据 A. 若数据类型是对象, 进行对象合并; B. 其它类型会进行数据覆盖, 覆盖原则: 组件 > 父behavior > 子behavior; 靠后的behavior > 靠前的behavior;

Demo演示: 针对数据是对象&非对象

// 组件级js
data: {
  sameObj: {
    val1: '[my-component]-同名数据类型是对象'
  },
  sameData: false
},
ready: function (){
  console.log('[my-component]- ready')
  console.log('[my-behavior]- 同名数据', this.data.sameObj, this.data.sameData)
},

// behavior级
data: {
  sameObj: {
    val1: '[my-behavior]-同名数据类型是对象',
    val2: '[my-behavior]-体现同名数据类型做合并'
  },
  sameData: true
},

上述代码表现形式如下: 同名数据对象做合并, 同名数据非对象做覆盖. 微信小程序之behaviors

3. 若有同名的生命周期函数 -> 不会被覆盖、而是在对应的触发时机内逐个调用: A. 不同的生命周期之间, 遵循组件生命周期的执行顺序; B. 同种生命周期函数: ①. behavior优先于组件执行; ②. 子behavior优先于父behavior执行; ③. 靠前的behavior优先于靠后的behavior执行; C. 如果同一个 behavior 被一个组件多次引用,它定义的生命周期函数只会被执行一次;

应用场景

相信到了这里, 你应该明白了Demo演示中控制台的输出是基于什么来输出的, 接下来我们看看什么样的应用场景会考虑使用该属性呢? 如下图, 有个中间弹窗组件&&底部弹窗组件, 均内聚有如下功能点: A. 触发某一条件后, 出现该弹窗; B. 点击遮罩层, 关闭弹窗; 微信小程序之behaviors 考虑下如果将弹窗显示跟隐藏的逻辑放在behaviors里面, 是否能避免同份代码逻辑写2遍的问题呢.

Page中不能使用behaviors、只能在Components中使用!!!!!! 故若遇到真想使用behaviors属性的页面, 试试把某块页面内容抽离成组件, 然后引用组件的方式去实现.

最后

behaviors是个数组, 因为我们可以引入多个behavior, eg: [behaviorA, behaviorB, behaviorC, ...]

转载自:https://juejin.cn/post/6922030842663403527
评论
请登录