组件

billund定位是一个模块化框架,组件无疑就是一个重要的组成部分。在billund的组件概念,组件是由数据生成逻辑(dataGenerator)、模板(react|vue)、store配置(redux|vuex)组成,是一个可以完整自运行的自洽组件。

组件通过一个配置文件将这些内容关联起来,配置文件可以理解为就是组件的入口。配置文件要求暴露出来一个对象,其中字段如下:

name

组件的唯一标识,controler层通过name来引用组件。同一个项目内注册的组件的name不能重复。

actions

暴露出去的action常量,让代码能更优雅,例如:

 - action.js

const BTN_CLICKED = 'billund-widget-test-widget/btn-clicked';

module.exports = {
    BTN_CLICKED
};


 - config.js
module.exports = {
    name: 'billund-widget-test-widget',
    actions: require('./action.js')    
};

constants

希望暴露出去给外部使用的常量

dataGenerator

dataGenerator的定义是组件的初始化数据逻辑,是一个es6GeneratorFunction,有可能会同时运行在nodejs端和browser端。方法接收一个从controler传入的object参数,同时this指向对应的上下文(nodejs端是指向koa的上下文,browser端是指向前置处理器的上下文)。方法要求返回一个object结果,这个object会是传入模板的props,同时也是store的组件state,从而后续可以通过redux|vuex进行操作。一个常见的dataGenerator如下:

'use strict';

const REVIEW_URL = '/my/test/api.json';

/**
 * 获取数据
 *
 * @param {Object} context - 上下文
 * @param {Object} query - 查询对象
 * @return {Object}
 */
function* getReviews(context, query) {
    /*
        我们有一个fetch中间件,将它挂载了koa & billund-supportor的上下文上,从而可以通过调用
     */
    return context.fetch(REVIEW_URL, {
        data: query
    }).then((json) => {
        if (!(json && json.respCode == 200 && json.data)) {
            throw new Error('invalid data');
        }
        return json.data.items || [];
    }).catch((e) => {
        console.log(e);
        return [];
    });
}

function* execute(params) {
    const query = {
        id: params.brandId
    };
    const reviews = yield getReviews(this, query);
    return {
        items: reviews
    };
}

module.exports = execute;

在执行过程中,如果发生了错误,可以直接抛出异常,billund会捕获这个异常,并且体现在renderPlugin的执行结果中。同时,如果这个组件是一个首屏模块,会自动在前端进行重试。

ps: 如果没有提供dataGenerator,我们会默认将controler传递的params直接传递给模板。

template

billund的组件模板同时支持ReactVue,会通过文件名的后缀来自动识别。和所有同构框架一样需要注意的是,如果你在模板文件中引用了一个非同构的模块,请在组件对应的生命周期内(例如ReactcomponentDidMountVuemounted)引入。模板最后需要暴露出来一个模板对象(ReactElement|VueElement)。

storeConfig

通常来说,组件都会存在交互行为,无论是响应其他组件的行为或者是自身的行为。我们默认根据组件的类型引入了对应的状态管理工具(React -> Redux,Vue -> Vuex),从而能够通过单向数据流来减轻复杂交互的实现难度。我们的store中的state也是模块化的,除了全局的state,每个组件会掌握一个自身的state。我们可以通过改变这个自身的state来改变组件的展示,也可以通过dispatch一个action来向外部发出交互的通知。

billund支持通过配置一个storeConfig对象来设置对应的store。

ps:以下内容可能需要部分ReduxVuex的知识(React -> Redux,Vue -> Vuex,取决于您所使用的渲染框架),如果您对他们不太了解,请先移步了解一下它们。

React

React组件的storeConfig支持两个字段:

ownReducer

ownReducer是一个用来操作组件自身的statereducer,概念和ReduxcombineReducer非常相似。ownReducer会接收两个参数,state与action,其中state是组件自身的局部stateaction是dispatch出来的action。ownReducer在需要更改组件state的情况下,要求返回一个新的对象,这个新的对象会成为组件新的state。

mapStateToProps

mapStateToProps就是Redux概念中的mapStateToProps。方法接收三个参数,分别是state(全局store的state),ownState(组件自身的局部state),initialProps(组件的初始数据,就是dataGenerator传递过来的对象)。

Vue

我们通过Vuex的modules来实现了store的模块化,所以storeConfig支持以下字段:

actions

actions是一个对象,里面包括了组件注册需要响应的action。对于模块内部的 action,它接收两个参数,分别是contextpayload。其中,context.state 是局部组件state,根节点的状态是 context.rootStatepayload是dispatch action时携带的参数。

mutations

mutations是一个对象,里面包含了组件注册需要响应mutationmutation接收两个参数,分别是state(组件的局部状态)与payload(commit时携带的参数)。

getters

getters是一个对象,里面包含了组件要注册的gettergetter同时接收三个参数,分别是state(组件的局部状态),getters(所有的getters),rootState(全局的state)。

state -> props

默认情况下,我们会将template中组件的props直接与组件对应module中对应的state对应,state变更会直接自动引起props的变更,不需要开发者手动关联。

results matching ""

    No results matching ""