likes
comments
collection
share

《你不会还不知道“behavior”吧》之介绍

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

对于我来说,有两个.

  • 疑惑

    在不断的开发中,会发现工具库到做了不少.但对于组件界面有没有类似于基类并可以多继承的东东呢?

  • 实践中的问题

    在落地到我们实践中,你会发现.在不断的优化代码.有很多相同特性或者功能集,在界面或者组件里重复的出现.此时,你就需要考虑把代码抽离.抽离方式很多,但总不能一直使用工具或者组件吧.虽然可以解决部分问题.但不优雅笨重

千呼万唤始出来.我们的主角behavior终于登场了.

  • behaviors是谁?

    • 含义

      我理解是用于组件界面代码共享的特性.类似有fluttervuemixins.通俗一点就是多继承混入.最最最关键的一点.它是有自己的生命周期.

      《你不会还不知道“behavior”吧》之介绍 它是可以被Page自定组件引用的.

    • 组成

      它是由属性数据生命周期函数四个大模块组成的.提高了代码的复用性.表现形式为js文件.具体参数如下所示

      参数类型描述
      propertiesObject Map组件的对外属性,是属性名到属性设置的映射表
      dataObject组件的内部数据
      observersObject组件数据字段监听器,用于监听 properties 和 data 的变化(很有用)
      methodsObject组件的方法,包括事件响应函数和任意的自定义方法
      behaviorsString Array引入其它的 behavior
      createdFunction实例刚刚被创建时执行.切记此时不能调用setData
      attachedFunction实例进入页面节点树时执行
      readyFunction组件布局完成后执行
      movedFunction实例被移动到节点树另一个位置时执行
      detachedFunction实例被从页面节点树移除时执行
      relationsObject组件间关系定义
      lifetimesObject新的组件生命周期声明对象
      pageLifetimesObject新的组件所在页面的生命周期声明对象
      definitionFilterFunction定义段过滤器,用于自定义组件扩展
    • 创建

      实践一下.可以在项目中创建一个behaviors目录,用于存放通用behavior.如下所示

      《你不会还不知道“behavior”吧》之介绍 由于behaviors本质就是js文件,只需要在behaviors文件夹下,创建对应的js文件就行,然后在js文件里,创建behavior方法.如下所示

      module.exports = Behavior({
      
          properties: {
              name:"哈哈我是对外公开的"
          },
          data: {
              title:"我是测试数据哦"
          },
          // 私有方法集
          methods: {
             // 测试方法
             testApi() {
                 console.log("我是testApi")
             }
          },
      
          // 旧的生命周期函数,可以保持对 <2.2.3 版本基础库的兼容
          created() {},
          // 组件生命周期声明对象
          lifetimes: {
              // 新的生命周期函数
              created() {},
          }
      });
      
    • 引用

      page自定义组件引用behaviors的时候.behaviors的属性、数据和方法都会合并到被引用者中.

      简单来说.

      如果你引用了behavior,那就相当于你继承了它,既然继承了,那必然父类有的你都有,你特有的父类必然没有哦.当然也是可以可以重写父类对外公开的方法哦.

      我们已经创建的第一个behavior,下面一起看一下怎么引用

      • 界面中引用

        const test = require("../../behaviors/testbehaviors")
        Page ({
           behaviors: [test],
        })
        
      • 组件中引用

        const test = require("../../behaviors/testbehaviors")
        Component({
          behaviors: [test],
        })
        
    • 调用和重写方法

      • 调用方法

        从上面的实例中,我们是可以直接调用test中的方法的.就如调用自己的方法一样,如下所示

        onLoad() {
           this.testApi();
        },
        

        输出结果 《你不会还不知道“behavior”吧》之介绍

      • 重写方法

        这里我们直接重写testApi方法,如下所示

        testApi() {
           console.log("我是index")
        },
        

        运行结果 《你不会还不知道“behavior”吧》之介绍

      behavior虽然可以解决多继承的问题,但多个父类冲突时,那子类应该怎么抉择呢.

      • 同名属性和方法

        1.如果当前组件存在同名属性或者方法,以当前组件为准

        2.如果当前组件没有同名属性或者方法.以behaviors字段中定义最后一个behavior中的属性或方法为准.

        3.在 2 的基础上,若存在嵌套引用 behavior 的情况,则规则为:引用者 behavior 覆盖 被引用的 behavior 中的同名属性或方法

      • 同名数据字段

        1.如果同名数据字段都是对象,就合并

        2.其余情况,执行覆盖原则 引用者 behavior >  被引用的 behavior 、 靠后的 behavior > 靠前的 behavior。(优先级高的覆盖优先级低的,最大的为优先级最高)

      • 生命周期和监听函数

        由于特殊性,他们不会被覆盖,只能向上逐个调用.

        调用规则如下所示:

           `behavior` 优先于组件执行;
           `被引用的 behavior` 优先于 `引用者 behavior` 执行;
           `靠前的 behavior` 优先于 `靠后的 behavior` 执行;
        

        当然同一个behavior被多个组件引用的时候,生命周期和监听函数不会被重复执行.