herbjs 简明数据流


最近在使用herbjs做支付宝小程序的开发,在熟悉了开发模式之后,还是挺好用的。

小程序运行机制

写小程序的感觉,更像是在写ract,然而这两者的机制是不一样的。

小程序的框架包含两部分View视图层(可能存在多个)、App Service逻辑层(一个),View层用来渲染页面结构,AppService层用来逻辑处理、数据请求、接口调用,它们在两个线程里运行。

视图层使用WebView渲染,逻辑层使用JSCore运行。

视图层和逻辑层通过系统层的JsBridage进行通信,逻辑层把数据变化通知到视图层,触发视图层页面更新,视图层把触发的事件通知到逻辑层进行业务处理。

image-20200816164049483

小程序的setData并不是实时的,而是需要两个线程通过 JsBridge 进行通信完成,在性能优化方面,需要考虑:

  1. 避免频繁的 setData,容易造成卡顿,渲染出现延迟
  2. 避免setData频繁传递大量数据
  3. 避免后台页面setData,用户无法感知,会抢占前台页面的执行

herbjs 与原生开发框架相比

原生框架数据以page为单位,进行管理。

herbjs 吸收了 vuex 的精华,给小程序增加了,全局 store,页面store,等一系列的 vuex 功能。还支持 typescript,插件体系等功能。

区别于 uni-app,taro,这些框架,herbjs 并没有修改小程序本身的逻辑,原有的生命周期都还在,原有的写法也都适用,更多的可以看成是原生小程序的增强版。

个人觉得,简明的数据流是这个框架最优雅的地方,方便大量 vue 开发者快速上手开发。

官方文档: https://www.yuque.com/herbjs/doc

官方文档,其实说的已经比较明白了,值得多看几遍。

简明数据流

项目地址:https://github.com/Yaob1990/leran_herbjs

页面级别数据流

页面中,通过 setData数据

Page<IPageState, IPageMethods, IPageStore>({
  onLoad(options) {
    this.init();
  },
  data: {
    num: 0,
  },
  plus() {
    this.setData({
      num: ++this.data.num,
    });
  },
  minus() {
    this.setData({
      num: --this.data.num,
    });
  },
});

组件中数据流

外部传入参数,注意如果是监听事件必须是on开头

Component<IComponentData, IComponentProps, IComponentMethods>({
  mapStateToData: [],
  data: {
    text: 'component',
  },
  props: {
    onPlus: () => {},
    onMinus: () => {},
  },
  didMount() {},
  didUnmount() {},
  methods: {
    plus() {
      this.props.onPlus();
    },
    minus() {
      this.props.onMinus();
    },
  },
});

组件使用:

<action onPlus="plus" onMinus="minus"></action>

页面 store 数据流

Page<IPageData, IPageMethods, IPageStore>({
  plus() {
    this.commit('plus');
  },
  minus() {
    this.commit('minus');
  },
  multiply() {
    this.dispatch('multiplyAsync');
  },
});

store 部分


Store<IPageState, IPageGetters, IPageMutations, IPageActions>({
  state: {
    num: 0,
  },
  // 全局 Getter 可以被 App、Page、Component 都能访问到
  // 页面 Getter 只能被当前 Page 和 当前 Page 内的 Component 访问到
  getters: {
    desc: ({ state, getters }) => {
      if (state.num > 0) {
        return '正值';
      } else if (state.num < 0) {
        return '负值';
      } else {
        return '零';
      }
    },
  },
  mutations: {
    plus(state) {
      state.num = ++state.num;
    },
    minus(state) {
      state.num = --state.num;
    },
    multiply(state) {
      state.num = state.num * 10;
    },
  },
  actions: {
    async multiplyAsync({ state, commit, dispatch }, payload) {
      setTimeout(() => {
        commit('multiply');
      }, 5000);
    },
  },
});

全局 store

全局 store 和页面类似,只是多一个 $global参数,详见文档。

开发体会

小程序的开发框架百花齐放,uni-app,taro,mpvue。

然而,自己也只是停留在会用的程度,没有再去想一想为什么可以这样编译,内部的原理。这阶段的工作估计会长期和小程序打交道,希望自己能够深入的研究小程序的背后逻辑,而不仅仅会用就行。

道阻且长,同志加油。


文章作者: Yao
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Yao !
 上一篇
vue3 h5 脚手架 vue3 h5 脚手架
vue 3 终于发布了正式版。 也把自己用了很久的 h5 脚手架更新了一波,所有依赖都升级到最新,后续h5开发就直接使用最新的脚手架进行开发。 后续还会增加多页面的脚手架,多页面写的真的不多,但是配置还是有点意思的~ 本次脚手架,抛弃了单元
2020-09-21
下一篇 
async await 的终极封装 async await 的终极封装
async await 的终极封装在看同事代码时候,看到下面这一段,有点意思。 let [res,error] = await getList() if(error){ // 错误处理 } // 业务处理 注意,这里代码没有使用try
2020-08-06
  目录