当前位置: 首页 > 工具软件 > iMvc > 使用案例 >

同构MVC框架——React-IMVC的简单上手

金阳曜
2023-12-01


React-IMVC是什么

react-imvc 是 Isomorphic(同构) mvc 的 react 实现,它是一个 Web 框架。通过 react-imvc,我们可以更便利地实现同构 Web 应用的开发

作为同构应用,它可以

  • 一条命令启动完整的开发环境
  • 一条命令编译和构建源代码
  • 一份代码,既可以在 node.js 做服务端渲染(SSR),也可以在浏览器端复用后继续渲染(CSR & SPA)

react-imvc 里的 MVC 三个部分都是 Isomorphic 的,所以它可以做到:只编写一份代码,在 Node.js 里做 Server-Side-Rendering 服务端渲染,在 Browser 里做 Client-Side-Rendering 客户端渲染。

React-IMVC的安装和启动

npm install --save react react-dom@16.8.0 react-imvc@16.8.0

在 package.json 中添加启动命令

{
    "scripts": {
        "start": "react-imvc start"
    }
}

使用React-IMVC实现简单的Todo List

react-imvc项目文件的基本结构为

project
├─ imvc.config.js
└─ src
   ├─ index.js
   └─ page
      └─ Todo
         ├─ Controller.js
         ├─ Model.js
         └─ View.js

src 目录下的 index.js 即为路由入口,每个page为一个文件夹

// index.js
export default [
    {
        path: '/',
        controller: () => import('./page/Todo/Controller')
    }
]

对于每个page而言,View 是可选的,当页面视图结构较为简单时,可以将 View 写在 Controller 里,同时,当 View 的结构比较复杂,包含多个子组件(可以是React组件)时,也可以使用多个 js/jsxView 进行拆分

      └─Todo
        ├─ Controller.js
        ├─ Model.js
        └─ View
          ├─ Footer.jsx
          ├─ Header.jsx
          ├─ index.jsx
          ├─ List.jsx
          └─ Todo.jsx

index.jsx 中向Controller进行暴露

// index.jsx
import React from 'react'

import Header from './Header'
import List from './List'
import Footer from './Footer'

export default function View() {
  return (
    <div>
        <Header></Header>
        <List></List>
        <Footer></Footer>
    </div>
  )
}

每个page的 Model.js 对该页面中的数据进行状态管理,定义页面的初始状态 initialState 和改变状态的函数 actions,state 在创建后后存储在 controller.store 下,通过 relite 进行管理。在 action 中,state 应当是不可变数据,action 是不包含副作用的纯函数。

// Model.js
export const initialState = {
    todos: [
        { id: 1, text: 'sleeping', done: true },
        { id: 2, text: 'eating', done: true },
        { id: 3, text: 'coding', done: false }
    ]
}

export const ADD_TODO = (state, todo) => {
    const newTodos = [todo, ...state.todos]
    return {
        ...state,
        todos: newTodos
    }
}

Model.js 也是可选的

Controller.js 中,引入 Model 和 View

// Controller.js
import Controller from 'react-imvc/controller'

import * as Model from './Model'
import View from './View'

export default class Todo extends Controller {
    View = View
    Model = Model
}

在 Controller 中还具有一些生命周期方法

使用 componentDidFirstMount 可以在页面创建时读取 localstorage 使用本地存储

// Controller.js
componentDidFirstMount() {
   const localData = localStorage.getItem('react-imvc-todo')
   const todos = (localData && JSON.parse(localData)) || []
   this.store.actions.INITIAL_TODOS(todos)

   this.store.subscribe((data) => {
      localStorage.setItem('react-imvc-todo', JSON.stringify(data.currentState.todos))
   })
}

项目源码

react-imvc-todo

 类似资料: