摘要:介紹首先是一個基于和的數據流方案,然后為了簡化開發體驗,還額外內置了和,所以也可以理解為一個輕量級的應用框架。
介紹(dva.js)
dva 首先是一個基于 redux 和 redux-saga 的數據流方案,然后為了簡化開發體驗,dva 還額外內置了 react-router 和 fetch,所以也可以理解為一個輕量級的應用框架。
特性易學易用,僅有 6 個 api,對 redux 用戶尤其友好,配合 umi 使用后更是降低為 0 API
elm 概念,通過 reducers, effects 和 subscriptions 組織 model
插件機制,比如 dva-loading 可以自動處理 loading 狀態,不用一遍遍地寫 showLoading 和 hideLoading
支持 HMR,基于 babel-plugin-dva-hmr 實現 components、routes 和 models 的 HMR
前言我的個人理解:dva的核心其實是 saga的封裝,將action,reducer等等全部引入到model中。
過多的廢話也就不再闡述了,欲知詳情,請看官網,本文的目的就是快速開始,讓一個擁有react+redux基礎的人可以快速使用dva.js
"深入"配置環境安裝依賴之類的就不多說了,請看官方文檔
dva new dva-quickstart
我們得到初始項目,目錄結構如下:
接下里將會逐個目錄解釋,請注意看注釋
import dva from "dva"; //引入依賴 import "./index.css"; // 1. Initialize const app = dva(); //初始化 dva應用 // 2. Plugins // app.use({}); //使用中間件 // 3. Model // app.model(require("./models/example").default); // 加載model層 (后面詳細解釋model) // 4. Router app.router(require("./router").default); // 引入router // 5. Start app.start("#root"); // 掛載dva應用
基本上就是這樣,多余的沒什么好說的
路由匹配 router.jsimport React from "react"; import { Router, Route, Switch } from "dva/router"; // 引入 router,用的就是 react-router import IndexPage from "./routes/IndexPage"; // 引入路由綁定的高階組件 // 按照從上到下的順序開始匹配url規則,匹配到了就是展示對應的組件view function RouterConfig({ history }) { return (路由頁面 routes/IndexPage.js); } export default RouterConfig;
在routes目錄下,是路由頁面,由多個高階組件渲染而成,當然,剛初始化的項目自然沒有寫高階組件,在后面的實戰操作中,我們將以 路由頁面 => 高階組件 => 基礎組件 路由綁定model層,高階組件綁定路由的action事件,基礎組件綁定原生事件,在路由中觸發action更新數據流 的邏輯 完成一個簡單標準的dva過程
import React from "react"; import { connect } from "dva"; import styles from "./IndexPage.css"; // 在這個方法中,我們返回一個dom結構 // 并且 在圓括號中 可以接受一個大對象(包含很多東西),也可以解構 只取其中的state和dispatch,具體可以在后面看 function IndexPage() { return (); } IndexPage.propTypes = { }; // 這里 connect方法就是redux的connect,后面的IndexPage表示綁定的高階組件 // 在connect的第一個括號中,是可以拿到所有的model對象,這樣就可以把對應的model對象綁定到我們的高階組件上 export default connect()(IndexPage);Yay! Welcome to dva!
- To get started, edit
src/index.js
and save to reload.- Getting Started
看了上面的注釋很蒙也沒關系,因為紙上談兵,甚至,我兵都沒有出來,你只需要知道,connect的作用及過程就好了
數據模型 model/emample.jsexport default { namespace: "example", // 命名空間 作為 connect方法 中獲取model對象state的 id state: {}, // 初始化state subscriptions: { // 訂閱 setup({ dispatch, history }) { // eslint-disable-line }, }, effects: { // 異步action的handler *fetch({ payload }, { call, put }) { // eslint-disable-line yield put({ type: "save" }); }, }, reducers: { //react-redux的reducers 用來接收action并且處理數據更新 save(state, action) { return { ...state, ...action.payload }; }, }, };
當我們在高階組件中通過connect綁定了高階組件和model,并且在index.js中引入這個model,就可以使用標準流程:
在subscriptions方法中訂閱路由變化,當路由與高階組件相對應,調用effects請求數據,拿到數據reducer更新數據
代碼就不貼了,大家應該都知道這里面做什么
公共服務 services/example.js這里封裝了一些公共使用的方法
"淺出"項目地址:https://github.com/zhaowanhua...
接下來,我們將quick-start項目改造成一個按照dva標準流程的小項目(如上圖),幫助大家理解和使用
首先我們把上面那些文件夾下面的文件全部刪干凈
import dva from "dva"; import "./index.css"; import createHistory from "history/createBrowserHistory"; // 這個方法里面 可以配置router的 路由模式,比如hash或者H5 histroy, // 具體區別可以參考我的文章 vue-router,單頁應用原理一致的 const app = dva({ history: createHistory() }); // 2. Plugins // app.use({}); // 3. Model app.model(require("./models/List").default); // 引入model // 4. Router app.router(require("./router").default); // 5. Start app.start("#root");創建基礎組件 components/Item.js
import React from "react"; const Item = ({ num, id, OnDelete }) => { return (
export default { namespace: "list", // 這個namespace 是model的唯一識別id,在connect中需要使用這個綁定 state: {}, subscriptions: { setup({ dispatch, history }) { // eslint-disable-line return history.listen(({ pathname }) => { if (pathname === "/") { dispatch({ type: "fetch", payload: {} }); } }); }, }, effects: { * fetch({ payload }, { call, put }) { // eslint-disable-line // 這里假裝 獲取到了服務器的數據 const fetchData = [0, 1, 2, 3] yield put({ type: "save", list: fetchData }); }, }, reducers: { // 保存 save(state, action) { return {...state, list: action.list }; }, // 新增 add(state, action) { const [..._arr] = {...state }.list; _arr.push(_arr.length) return { ...state, list: _arr } }, // 刪除 del(state, action) { return { ...state, list: state.list.filter((item, index) => { return index !== action.id }) } }, }, };
寫好model 是要在index.js中引入的,不然沒有效果
創建高階組件 components/List.jsimport React from "react"; import Item from "./Item" // 通過prop 把路由頁面的action觸發方法綁定過來,傳遞給子組件(OnDelete),也可以在當前組件觸發,如OnAdd function List({ OnAdd, OnDelete, list }) { const List = list.map((num, index) =>創建路由頁面 routes/IndexPage.js- ); return (
{List}); } List.propTypes = {}; export default List;
import React from "react"; import { connect } from "dva"; import List from "../components/List" //我們在路由頁面里面渲染高階組件,寫好action,通過prop傳遞給基礎組件 // 這里引入的list 對應 model中的namespace function IndexPage({ dispatch, list }) { function handleAdd() { dispatch({ type: "list/add" }); } function handleDelete(id) { dispatch({ type: "list/del", id: id, }); } return (總結); } IndexPage.propTypes = {}; // 通過connect方法綁定路由頁面和model,你可以把connect方法的第一個參數(方法里的) 打印出來看看都有什么東西,不要讓解構擾亂了你的眼睛,connect((obj)=>{console.log(obj)})() export default connect(({ list }) => { return list; // 這里是state中的list,通過connect,在每次數據更新的時候,流向我們的view,更新視圖,你可以在這里"打樁",看看具體的數據流動 })(IndexPage);
以上是我最近學習的想法和思考后得到的內容,希望對大家有所幫助,寫的比較隨意,在內容中如果有問題或者想法不對,請予指正,也可以提出新的問題,我們共同探究.
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/96684.html
摘要:多端統一開發框架優秀學習資源匯總官方資源項目倉庫官方文檔項目倉庫官方文檔微信小程序官方文檔百度智能小程序官方文檔支付寶小程序官方文檔字節跳動小程序官方文檔文章教程不敢閱讀包源碼帶你揭秘背后的哲學從到構建適配不同端微信小程序等的應用小程序最 Awesome Taro 多端統一開發框架 Taro 優秀學習資源匯總 showImg(https://segmentfault.com/img/r...
摘要:哈哈,我理解,架構就是骨架,如下圖所示譯年月個有趣的和庫前端掘金我們創辦的使命是讓你及時的了解開發中最新最酷的趨勢。 翻譯 | 上手 Webpack ? 這篇就夠了! - 掘金譯者:小 boy (滬江前端開發工程師) 本文原創,轉載請注明作者及出處。 原文地址:https://www.smashingmagazine.... JavaSrip... 讀 Zepto 源碼之代碼結構 - ...
摘要:在符號位中,表示正,表示負。我們知道對于整型來說,內存中存放的是該數的補碼。在計算機系統中,數值一律用補碼來表示和存儲。表示有效數字,。規定對于位的浮點數,最高的位是 ...
摘要:進入當前程序的學習系統的所有樣本稱作輸入,并組成輸入空間。結束語注意這篇文章僅僅是我接下來的機器學習系列的第一篇,后續還會有更多的內容。 往期回顧:統計學習方法第...
閱讀 3722·2021-10-12 10:11
閱讀 1989·2019-08-30 15:53
閱讀 1594·2019-08-30 13:15
閱讀 2310·2019-08-30 11:25
閱讀 1806·2019-08-29 11:24
閱讀 1656·2019-08-26 13:53
閱讀 3528·2019-08-26 13:22
閱讀 1770·2019-08-26 10:24