国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

更好用的數(shù)據(jù)流管理框架:Vanex發(fā)布了~

weakish / 1517人閱讀

摘要:基于的管理框架,提供簡(jiǎn)單快捷的開發(fā)范式。這里的更改會(huì)對(duì)請(qǐng)求參數(shù)生效只針對(duì)名字是的進(jìn)行下面鉤子函數(shù)的執(zhí)行用于在執(zhí)行之后觸發(fā)。

vanex

基于mobx & mobx-react的React store管理框架,提供簡(jiǎn)單快捷的開發(fā)范式。使用模式類似dva,但用起來(lái)比dva更簡(jiǎn)單,開發(fā)效率更高!

github地址: https://github.com/alibaba/vanex
example地址: https://github.com/alibaba/va...

特點(diǎn)

三個(gè)API搞定問題!簡(jiǎn)單易上手,開發(fā)效率高。

如何使用

vanex提供了一鍵初始化的start方法,入口文件可以像下面這樣開始:

import React from "react";
import App from "./App";

import {
    start,
} from "vanex";

// model
import user from "./models/User";
import todos from "./models/Todos";

start({
    component: App,
    container: "#root",
    models: {
        user,
        todos
    }
});

所以,只需要把你的model(類似于tarot的module)、React Container Component、Middleware(可選)、Relation傳遞進(jìn)來(lái),應(yīng)用就能跑起來(lái)了。

介紹下幾個(gè)概念:

model: 數(shù)據(jù)管理,區(qū)別于tarot,其只有:name命名空間以及data、action兩個(gè)核心部分,action部分可以同時(shí)存放類似于Reducers以及Effects兩個(gè)部分的操作(作為優(yōu)化,后續(xù)這里可以做拆分);

middleware:中間件,用于輔助異步處理。model重定義的一個(gè)action最終被執(zhí)行的流程是這樣的:首先其會(huì)被mobx的action函數(shù)包一層,以避免掉每次更改數(shù)據(jù)都會(huì)觸發(fā)一次UI的重新渲染,然后其會(huì)被各個(gè)中間件依次執(zhí)行,而每個(gè)中間件都有before/after/error三個(gè)操作,可以在不同的操作中對(duì)每一種操作做統(tǒng)一的處理;

relation:用于不同model之間的通信,基于監(jiān)聽訂閱模式。

基于vanex的開發(fā)范式的container Component也是UI Component,UI Component像下面這樣:

import React, {Component, PropTypes} from "react";

// components
import UserLogin from "./components/UserLogin";
import UserDetail from "./components/UserDetail";
import Todos from "./components/Todos";

import {
    inject,
    observer,
} from "vanex";

// 注意先observer,后inject
@inject("user")
@observer
export default class App extends Component {
    render() {
        // const user = this.props.user.toJSON();
        console.log(this.props.user.toJSON());
        const {user} = this.props;

        console.log("user.isLogin:", user.isLogin);

        if (user.isLogin !== true) {
            return ;
        }

        return (
            
); } }

這里的oberser來(lái)自于mobx的observer,inject則來(lái)自于mobx-react。如果想給一個(gè)Component同時(shí)注入多個(gè)model,則可以像下面這樣:

// start
import React from "react";
import App from "./App";

import {
    start,
} from "vanex";

// model
import user from "./models/User";
import todos from "./models/Todos";

start({
    component: App,
    container: "#root",
    models: {
        user,
        todos
    }
});
import {
    inject,
    observer,
} from "vanex";

@inject(
    stores => ({
        user: stores.user,
        todos: stores.todos,
    })
)
@oberser
class MyComponent extends Component{
    constructor(props, context) {
        super(props, context);
    }

    render() {
        const {
            user,
            todos,
        } = this.props;

        return (
            
{user.name}
); } }

mobx的observer API,用于將React Component變成observable的(動(dòng)態(tài)收集依賴),在對(duì)model中的某些數(shù)據(jù)做了操作之后,如果被修改的數(shù)據(jù)剛好被該React組件使用到了,就會(huì)觸發(fā)該組件的重新渲染,這也就是mobx能細(xì)粒度控制數(shù)據(jù)的原因所在。

mobx-react的inject API,用于指定將哪些model注入進(jìn)React Component(this.props.modelName),也就指定了該組件基于哪些數(shù)據(jù)做Observeable。

model

代碼類似于下面這樣:

import TodoItem from "./TodoItem";
import * as api from "../api";

export default {
    name: "Todos",
    data: {
        list: [],
    },
    syncs: {
        add(text, userId) {
            // 類似于Vue,對(duì)數(shù)組的操作會(huì)觸發(fā)UI的重新渲染
            this.list.push(new TodoItem({
                text,
                userId
            }));
        },
    },
    effects: {
        async getByUserId(userId) {
            let todos = await api.getTodosByUserId(userId);
            todos = todos.map(todo => new TodoItem(todo));
            // 類似于Vue,對(duì)數(shù)組的操作會(huì)觸發(fā)UI的重新渲染
            this.list = this.list.concat(todos);
        },
    }
};

model由以下幾個(gè)部分組成:

1、name: 當(dāng)前model的命名空間;

2、constants: 不可變常量;

3、data: 可操作數(shù)據(jù)部分;

4、syncs: 同步操作數(shù)據(jù)部分;

5、effects: 異步處理部分;

6、init: 初始化model后的回調(diào)方法;

7、autorun: 每次對(duì)數(shù)據(jù)進(jìn)行操作后都會(huì)自動(dòng)執(zhí)行的方法。

觸發(fā)action model內(nèi)部觸發(fā)

model內(nèi)部定義的Data數(shù)據(jù),會(huì)被賦值到model實(shí)例上,所以任何在Data中定義的數(shù)據(jù)都可以通過(guò)this.xxx的方式來(lái)引用,如下:

import fetch from "whatwg-fetch";

const pageSize = 20;

export default {
    name: "Applications",

    data: {
        dataSource: [

        ], // 列表顯示的數(shù)據(jù)

        detailPageVisible: false,

        campaignDetail: {},
    },

    syncs: {
        validate(value) {
            value = value ||"";

            // xxxx

            return {
                code: 200
            };
        },
    },

    effects:{
        async getList(payload = {}) {
            const {
                currentPage = 1,
            } = payload;

            const url = `/applications/list/${currentPage}?pageSize=${pageSize}`;

            let res = await fetch(url);

            res = res.body;

            const validateRes = this.validate(res);

            if(validateRes.code == 200) {
              this.dataSource = res.data; // 這樣就會(huì)觸發(fā)對(duì)應(yīng)Component的重新渲染
              this.currentPage = res.currentPage;
              this.totalItem = res.totalItem;
              this.totalPage = res.totalPage;
            }

            return res;
        },
    }
};

可以看到,更改數(shù)據(jù)則是直接給model實(shí)例賦值即可,簡(jiǎn)單直接高效,而且多次賦值只會(huì)觸發(fā)一次的重新渲染。你能想象如果一個(gè)頁(yè)面是一個(gè)list列表,用戶對(duì)列表中某一個(gè)進(jìn)行操作后,需要修改這一項(xiàng)的數(shù)據(jù)及顯示,只需要執(zhí)行類似于:

this.props.home.list[2].name = "New Name";

的代碼就能完成name的數(shù)據(jù)處理及頁(yè)面展示更改嗎?想想就激動(dòng)是不是。

有的同學(xué)會(huì)有:syncs和effects里面多次對(duì)model直接賦值會(huì)觸發(fā)UI的多次渲染的擔(dān)心,其實(shí)不會(huì)的,我們隊(duì)syncs以及effects里面的每一個(gè)方法都用會(huì)使用mobx的action做了一層包裝,從而來(lái)避免這個(gè)問題。

另外,我們也提供this.set()的輔助方法來(lái)方便的為model改值,所以你還可以這樣做:

this.set({
  dataSource: res.data,
  currentPage: res.currentPage,
  totalItem: res.totalItem,
  totalPage: res.totalPage,
});

這里會(huì)使用mobx的runInAction來(lái)統(tǒng)一執(zhí)行,從而保證UI渲染只執(zhí)行一次。

組件內(nèi)觸發(fā)

如下,簡(jiǎn)單直接:

import { inject, observer } from "vanex";

@inject("applications")
@observer
class Applications extends Component {
    constructor(props, context) {
        super(props, context);
    }

    clickHandler() {
      this.props.applications.getList(); // 直接執(zhí)行
    }

    render() {
      return (
        
); } }
Vanex插件機(jī)制

Vanex支持插件機(jī)制,使用的方式如下:

import { start, use } from "vanex";

import effectPlugin from "./effect-plugin";

use(effectPlugin);

// start代碼

目前已經(jīng)提供的插件列表如下:

onStateChange

用于監(jiān)聽數(shù)據(jù)發(fā)生改變的時(shí)候的觸發(fā)回調(diào)。格式如下:

export default {
    onStateChange: [event => {
        console.log(event);
    }]
};
onEffect

用于處理異步執(zhí)行執(zhí)行前(before)、后(after)、錯(cuò)誤(error)以及過(guò)濾哪些effects執(zhí)行該回調(diào),它在執(zhí)行的時(shí)候其實(shí)是以中間件的形式來(lái)執(zhí)行的。如果有類似于每次請(qǐng)求都自帶csrfToken的需求,則可以在before鉤子函數(shù)中組裝。

具體使用如下:

// Before exec action
function preLogger({
    type,
    payload
}) {
    console.log(`[${type}] params: `, payload);

    payload。csrfToken = "xxx"; // 這里的更改會(huì)對(duì)請(qǐng)求參數(shù)生效

    return payload;
}

// Action exec fail
function errorLogger({
    type,
    payload
}) {
    console.log(`[${type}] error: `, payload.message);
    return payload;
}

// After exec action
function afterLogger({
    type,
    payload
}) {
    console.log(`[${type}] result: `, payload);
    return payload;
}

export default {
    filter({
            type
        }) {
        return /^User/.test(type); // 只針對(duì)Model名字是User的進(jìn)行下面鉤子函數(shù)的執(zhí)行
    },
    before: preLogger,
    after: afterLogger,
    error: errorLogger,
};
onAction

用于在執(zhí)行syncs Action之后觸發(fā)。格式如下:

export default {
    onAction: [(
        actionName,
        actionArgs,
        result) => {
            console.log(`當(dāng)前執(zhí)行Action的名字:${actionName}`);
            console.log(`當(dāng)前執(zhí)行Action的參數(shù):${actionArgs}`);
            console.log(`當(dāng)前執(zhí)行Action的結(jié)果:${result}`);
        }]
};
getActionState

這個(gè)并不是Vanex插件,但是用于解決在組件中獲取當(dāng)前model中某個(gè)effect是否正在發(fā)送請(qǐng)求的問題,而這個(gè)狀態(tài)可以用于方便的控制Loading組件是否可見。因?yàn)檫@種需求非常普遍,所以Vanex直接內(nèi)置到內(nèi)部實(shí)現(xiàn)中。使用示例如下:

const {
    user
} = this.props;

const {
    loading: loginLoading,
    error: loginError
} = user.getActionState("user/login");
用于開發(fā)組件

有時(shí)候,我們并不想執(zhí)行頁(yè)面渲染,而是用Vanex來(lái)開發(fā)一個(gè)組件,這時(shí),還是可以使用start API,只要不傳如container值,就會(huì)返回一個(gè)React Component。

import React from "react";
import { render } from "react-dom";
import App from "./App";

// load middlewares
import middlewares from "./middlewares";

import {
    start,
    use,
} from "vanex";

use({
    onEffect: middlewares
});

// model
import user from "./models/User";
import todos from "./models/Todos";

// relation
import relation from "./relations";

// 驗(yàn)證start返回一個(gè)組件
const MyComponent = start({
    component: App,
    models: {
        user,
        todos
    },
    relation
});

render(, document.querySelector("#root"));
特點(diǎn)

簡(jiǎn)單易上手,開發(fā)效率高;

MVVM:Vanex實(shí)現(xiàn)了基于React的MVVM開發(fā)范式,簡(jiǎn)單直接,開發(fā)效率高;

更改store數(shù)據(jù):直接賦值;

觸發(fā)action:直接執(zhí)行store的action;

性能優(yōu)化:自動(dòng)做掉。

為什么基于mobx的開發(fā)范式更簡(jiǎn)單高效?

Mobx的實(shí)現(xiàn)思想和Vue幾乎一樣,所以其優(yōu)點(diǎn)跟Vue也差不多:通過(guò)監(jiān)聽數(shù)據(jù)(對(duì)象、數(shù)組)的屬性變化,可以通過(guò)直接在數(shù)據(jù)上更改就能觸發(fā)UI的渲染,從而做到MVVM、響應(yīng)式、上手成本低、開發(fā)效率高,在數(shù)據(jù)管理上需要再詳細(xì)闡述下其區(qū)別。

Redux是建議全局唯一Store的,多個(gè)Reducers也會(huì)在傳遞給react-redux之前被合并成一個(gè)root reducer,任何數(shù)據(jù)的更改(通過(guò)Reducer)都會(huì)通過(guò)這一個(gè)store來(lái)觸發(fā)整個(gè)UI樹的重新渲染,如果不做任何的性能優(yōu)化(pureRender等),就算VD(Virtual Dom)有了再高的效率提升,當(dāng)頁(yè)面數(shù)據(jù)量、DOM數(shù)量大了,性能消耗也是非常大的。另外一點(diǎn),Redux實(shí)現(xiàn)的對(duì)數(shù)據(jù)的管理是pull方式的,就是說(shuō)其只能等待應(yīng)用派發(fā)某個(gè)行為(Action),然后重新觸發(fā)UI的渲染,而做不到對(duì)行為的可預(yù)期;Mobx則不一樣,他是基于監(jiān)聽數(shù)據(jù)的屬性變化來(lái)實(shí)現(xiàn)的,而且是多store的,對(duì)于任何的數(shù)據(jù)變更都是第一時(shí)間知道的,所以其實(shí)現(xiàn)方式是基于push的監(jiān)聽訂閱模式而實(shí)現(xiàn),這樣,他就可以做到對(duì)數(shù)據(jù)的可預(yù)測(cè)以及細(xì)粒度的控制,甚至可以通過(guò)修改React組件生命周期的方式來(lái)減少性能的消耗,而無(wú)需使用者對(duì)這些細(xì)節(jié)關(guān)心。當(dāng)然這一切肯定是有了mobx對(duì)組件做observe操作才能實(shí)現(xiàn)的,所以也就有了observer用的越多,應(yīng)用性能越高的說(shuō)法。

感謝

Vanex的部分實(shí)現(xiàn)參考自MVVM框架:mobx-roof。

落地

1、內(nèi)容創(chuàng)作投放平臺(tái)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/87347.html

相關(guān)文章

  • 做一個(gè)基于react-scripts的腳手架

    摘要:前言作為官方的腳手架是相當(dāng)好用的。注意就是腳手架的核心配置代碼。另一個(gè)是使用,用戶通過(guò)增加修改配置。所以才有了今天的主題基于的腳手架,確切說(shuō)應(yīng)該是基于的腳手架。其中一定要填寫。前言 create-react-app作為facebook官方的react腳手架是相當(dāng)好用的。主要設(shè)計(jì)原理是將配置好的如Webpack,Babel,ESLint,合并到react-scripts這npm包中,用戶就可以...

    linkFly 評(píng)論0 收藏0
  • 數(shù)人云|當(dāng)K8S遇上微服務(wù)-京東金融PaaS平臺(tái)思考與實(shí)踐

    摘要:平臺(tái)上的微服務(wù)架構(gòu)應(yīng)用再來(lái)看一下我眼中的基于當(dāng)前最流行的微服務(wù)架構(gòu)的設(shè)計(jì)是什么樣的,即我們平臺(tái)上要運(yùn)行的典型應(yīng)用是什么樣的。 showImg(https://segmentfault.com/img/remote/1460000010900878); 8月19日的數(shù)人云Container Meetup上,張龍老師做了《基于Kubernetes的PaaS平臺(tái)的設(shè)計(jì)和思考》的精彩分享,分別...

    Imfan 評(píng)論0 收藏0
  • angular,react & vue

    摘要:由進(jìn)行開發(fā)和維護(hù),代發(fā)布于年月,現(xiàn)在主要是。狀態(tài)是只讀的,只能通過(guò)來(lái)改變,以避免競(jìng)爭(zhēng)條件這也有助于調(diào)試。文件大小為,而為,為。請(qǐng)記住,性能基準(zhǔn)只能作為考慮的附注,而不是作為判斷標(biāo)準(zhǔn)。使用的人員報(bào)告說(shuō),他們永遠(yuǎn)不必閱讀庫(kù)的源代碼。 本文當(dāng)時(shí)寫在本地,發(fā)現(xiàn)換電腦很不是方便,在這里記錄下。 angular,react & vue 2018/07/23 2016年,對(duì)于JavaScript來(lái)說(shuō)...

    jiekechoo 評(píng)論0 收藏0
  • 【全文】狼叔:如何正確的學(xué)習(xí)Node.js

    摘要:感謝大神的免費(fèi)的計(jì)算機(jī)編程類中文書籍收錄并推薦地址,以后在倉(cāng)庫(kù)里更新地址,聲音版全文狼叔如何正確的學(xué)習(xí)簡(jiǎn)介現(xiàn)在,越來(lái)越多的科技公司和開發(fā)者開始使用開發(fā)各種應(yīng)用。 說(shuō)明 2017-12-14 我發(fā)了一篇文章《沒用過(guò)Node.js,就別瞎逼逼》是因?yàn)橛腥嗽谥跎虾贜ode.js。那篇文章的反響還是相當(dāng)不錯(cuò)的,甚至連著名的hax賀老都很認(rèn)同,下班時(shí)讀那篇文章,竟然坐車的還坐過(guò)站了。大家可以很...

    Edison 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<