React--Umi和Dva_react dva-程序员宅基地

技术标签: react.js  前端  javascript  

目录

一、Umi

1.官网

2.安装与运行

3.配置式路由的创建

4.路由导航

4.1编程式--js的方式

4.2声明式--标签

5.重定向 --redirect

6.404页面

7.多级路由

8.约定式路由的创建

创建页面两种方式

二、Dva

1.官网

2.安装与运行

3.路由

4.路由导航

4.1编程式--js

4.2声明式--标签组件

5.model

6.读取数据

7.修改数据

8.effects--异步触发

扩展-Generator

9、effect使用

subscriptions 设置一个监听


一、Umi

简介:Umi,中文可发音为乌米,是可扩展的企业级前端应用框架。

           Umi 以路由为基础的(就是解决了之前使用react-router-dom的时候使用路由的复杂度)

1.官网

(1)2.0版本:https://v2.umijs.org/

(2)3.0版本:https://v3.umijs.org/

2.安装与运行

1.全局安装 : npm install -g umi@2 或者 yarn global add umi@2

2.测试安装版本: umi -v

3.新建文件夹 把cmd的路径切换到这个文件夹下

4.开始创建项目 yarn create @umijs/umi-app 或者 npm create @umijs/umi-app

5.下载依赖:cd到你刚才创建项目的文件夹下 npm install  或者  yarn

6.运行 yarn start  或者  npm start

3.配置式路由的创建

1.在src下的pages文件夹下 新建你对应的路由页面

2.配置路由规则 在.umirc.ts文件中进行配置

import { defineConfig } from 'umi';

export default defineConfig({
  nodeModulesTransform: {
    type: 'none',
  },
  routes: [
    { path: '/', component: '@/pages/index' },
    // 仿照默认的内容自行添加
    { path: '/home', component: '@/pages/home/home' },
    { path: '/phone', component: '@/pages/phone/phone' },
  ],
  fastRefresh: {},
});

4.路由导航

4.1编程式--js的方式

import React from 'react'
// 注意引用是来自于umi的
import {Link,history} from "umi"
export default function Topbar() {
    let fun=()=>{
        // 编程式导航
        history.push("/phone")
    }
  return (
    <div>
        <Link to="/">首页</Link>
        <Link to="/home">home</Link>
        <Link to="/phone">手机</Link>
        <hr />
        <button onClick={fun}>点我去手机</button>
    </div>
  )
}

4.2声明式--标签

借助Link 这个标签来完成,使用to属性来表明路径 。

import React from 'react'
// 注意引用是来自于umi的
import {Link} from "umi"
export default function Topbar() {
  return (
    <div>
        <Link to="/">首页</Link>
        <Link to="/home">home</Link>
        <Link to="/phone">手机</Link>

    </div>
  )
}

5.重定向 --redirect

umirc文件里面进行配置

import { defineConfig } from 'umi';

export default defineConfig({
  nodeModulesTransform: {
    type: 'none',
  },
  routes: [
    { path: '/index', component: '@/pages/index' },
    // 仿照默认的内容自行添加
    { path: '/home', component: '@/pages/home/home' },
    { path: '/phone', component: '@/pages/phone/phone' },
    // 路由重定向    exact精准匹配
    { path: '/', redirect:"/index",exact:true },
  ],
  fastRefresh: {},
});

6.404页面

1.创建对应404页面

2.配置404规则

import { defineConfig } from 'umi';

export default defineConfig({
  nodeModulesTransform: {
    type: 'none',
  },
  routes: [
    { path: '/index', component: '@/pages/index' },
    // 仿照默认的内容自行添加
    { path: '/home', component: '@/pages/home/home' },
    { path: '/phone', component: '@/pages/phone/phone' },
    // 路由重定向    exact精准匹配
    { path: '/', redirect:"/index",exact:true },

    // 404页面
    { path: '*', component: '@/pages/no/no' },
  ],
  fastRefresh: {},
});

7.多级路由

1.创建多级路由页面

2.配置多级路由规则(在对应的以及路由规则中进行嵌套)

 { 
      path: '/home', 
      component: '@/pages/home/home',
      // 配置多级路由
      routes:[
        { path: '/home/era', component: '@/pages/er/era' },
        { path: '/home/erc', component: '@/pages/er/erc' },
      ]
    
    },

3.千万不要忘了 设置二级路由出口 (在对应的路由页面中配置)props.children 多级路由的出口

8.约定式路由的创建

umi在创建路由时,我们也可以不需要配置路由规则,从而达到路由效果,这种方式就叫约定式 。

创建页面两种方式

1.手工创建:同原来

2.命令创建:在项目的根路径下 输入 umi g page 你要创建的页面名 (就会在pages文件夹下 自动创建对应的页面)

二、Dva

简介:

dva 首先是一个基于 reduxredux-saga 的数据流方案,然后为了简化开发体验 (dva就是对react进行了语法上面的简化 让我们在react中使用状态管理工具变得更简单)

redux-saga 就是redux进行异步操作的一个技术

1.官网

地址:DvaJS

2.安装与运行

1.全局安装 npm install -g dva-cli

2.测试 dva -v

3.cd到指定文件夹之下 dva new 你的项目名

4.cd到项目下面 npm install之后再启动

5.启动 npm start

3.路由

在dva中使用他内置的路由我们可以把路由页面创建到src下的routes文件夹中 当然我们也可以重新创建一个文件夹来容纳路由页面

1.创建路由页面

2.配置路由规则 src文件夹下的router.js文件中来进行编写

import React from 'react';
import { Router, Route, Switch } from 'dva/router';
import IndexPage from './routes/IndexPage';
// 1.引用路由页面
import Home from "./routes/home.jsx"
import Phone from "./routes/phone.jsx"
import User from "./routes/user.jsx"

function RouterConfig({ history }) {
  return (
    <Router history={history}>
      <Switch>
        <Route path="/" exact component={IndexPage} />
        {/* 2.配置路由规则 */}
        <Route path="/home" exact component={Home} />
        <Route path="/phone" exact component={Phone} />
        <Route path="/user" exact component={User} />
      </Switch>
    </Router>
  );
}

export default RouterConfig;

4.路由导航

4.1编程式--js

props.history.push("/去哪里")

注意:使用编程式导航必须在被路由所管理的页面中进行才可以,否则就要使用withRouter这个高阶组件来传递路由跳转的属性

import React from 'react'

// 引用Link组件来自于dva 的路由
import {Link,withRouter} from "dva/router"

function topbar(props) {
    let fun=()=>{
        // 编程式导航\
        // 在组件中定义了一个编程式导航
        // 但是在运行的时候发现push没有定义
        // 因为 在使用编程式导航的时候   由于当前组件不是被路由所管理的页面  那么他就不具备路由跳转的功能
        // 就会出现push没有定义

        // 所以我们就要使用HOC--高阶组件--withRouter来解决
        props.history.push("/user")
    }
  return (
    <div>
        
        {/* 声明式导航 */}
        <Link to="/">首页</Link>
        <Link to="/home">home</Link>
        <Link to="/phone">phone</Link>
        <Link to="/user">user</Link>

        {/* 编程式 */}
        <button onClick={fun}>点我去user</button>

    </div>
  )
}
export default withRouter(topbar)

4.2声明式--标签组件

import React from 'react'

// 引用Link组件来自于dva 的路由
import {Link} from "dva/router"

export default function topbar() {
  return (
    <div>
        {/* 声明式导航 */}
        <Link to="/">首页</Link>
        <Link to="/home">home</Link>
        <Link to="/phone">phone</Link>
        <Link to="/user">user</Link>
    </div>
  )
}

5.model

dva 通过 model 的概念把一个领域的模型管理起来,包含同步更新 state 的 reducers,处理异步逻辑的 effects,订阅数据源的 subscriptions 。

(dva中的model 就是用来把状态管理工具进行模块化设置的,为什么要设置模块化?

因为组件多了 数据与修改就变得很多,如果我们把一个项目的所有数据与修改都放在一起,后期维护就很麻烦,所以这个时候我们就可以进行模块拆分)

1.在src的modules文件夹中 创建对应的模块文件

2.编写内容

export default {
    namespace: 'userm',//命名空间---就是给当前这个模块起个名字(唯一的)
    state: {
        name:"我是user模块中的数据"
    },//存放数据的
    subscriptions: {//类似于一个监听  在里面可以绑定很多个监听的方案
    },
    effects: {//类似于vuex的actions  进行异步触发的
    },
    reducers: {//  修改上面的state的地方
    },
  };

3.把我们新建的模块和项目建立关联

在srtc下的index.js中建立

import dva from 'dva';
import './index.css';

// 1. Initialize
const app = dva();

// 2. Plugins
// app.use({});

// 3. Model  就是建立我们模块与项目的位置
// app.model(require('./models/example').default);
app.model(require('./models/homem').default);
app.model(require('./models/phonem').default);
app.model(require('./models/userm').default);

// 4. Router
app.router(require('./router').default);

// 5. Start
app.start('#root');

6.读取数据

import React from 'react'
import Topbar from "../components/topbar.jsx"
// 1.引用组件和模块的链接工具--connect  是一个方法  当这个方法被调用的时候他才是一个链接的高阶组件
import { connect } from 'dva'

function Home(props) {
  return (
    <div>
        <Topbar></Topbar>
        {/* props.state.你要引用的模块的命名空间名字.数据名 */}
        <h1>我想读取dva中模块的数据----{props.state.homem.name}</h1>
        <h1>我想读取dva中另一个模块的数据----{props.state.userm.name}</h1>
    </div>
  )
}
// 2.设置数据
export default connect(state=>({state}))(Home)

7.修改数据

1.在组件内通过dispatch来触发修改

import React from 'react'
import Topbar from "../components/topbar.jsx"
import { connect } from 'dva'
 function Phone(props) {
    let fun=()=>{
        // 触发dva的数据修改
        // dispatch({type:模块的命名空间名字/你的reducer的名字})
        props.dispatch({type:"phonem/UP_NAME"})
    }
  return (
    <div>
        <Topbar></Topbar>
        phone----{props.state.phonem.name}
        <button onClick={fun}>点我修改数据</button>
    </div>
  )
}
export default connect(state=>({state}))(Phone)

2.编写对应修改的reducers

export default {

    namespace: 'phonem',//命名空间---就是给当前这个模块起个名字(唯一的)
  
    state: {
        name:"我是phone模块中的数据"
    },//存放数据的
  
    subscriptions: {//类似于一个监听  在里面可以绑定很多个监听的方案
    
    },
  
    effects: {//类似于vuex的actions  进行异步触发的
    
    },
  
    reducers: {//  修改上面的state的地方
        // state:就是上面的数据源
        // payload就是接收dispatch的第二个参数
        UP_NAME(state,payload){
            return {...state,name:"我吧phone的数据修改了"}
        }
    },
  
  };

8.effects--异步触发

扩展-Generator

在dva中如果我们要使用effects来进行异步触发 那么我们需要使用es6中新特性之--- Generator

Generator 函数的作用:让我们的函数可以根据我们开发者的需求走走停停

1.如果我们想控制函数的执行或者暂停 那么我们需要把函数变成generator函数 就是在function关键字 与函数名之间加一个*号

    function *fun(){
            console.log(111);
            console.log(222);
            console.log(333);
        }

2.我们需要让函数根据我们的需要走走停停 那么我们就必须在函数中加入表示 来表明暂停的位置是哪里 yield(就是函数暂停的分割线)

   function *fun(){
            console.log(111);
            yield
            console.log(222);
            yield
            console.log(333);
        }

3.我们在调用的时候 还需要告诉当前的generator函数 你要执行 next()

 function *fun(){
            console.log(111);
            yield
            console.log(222);
            yield
            console.log(333);
        }
        // 我们要执行函数中的内容
        let funger=fun()
        // 想让函数执行
        funger.next()
        funger.next()

9、effect使用

1.在组件中还是使用dispatch来触发

import Topbar from "../components/topbar.jsx"
import {connect} from "dva"
 function User(props) {
    let fun=()=>{
        // 触发effects进行异步操作
        // props.dispatch({type:"你要调用的模块命名空间名字/effect的名字"})
        props.dispatch({type:"userm/LINK"})
    }
  return (
    <div>
        <Topbar></Topbar>
        user
        
       <button onClick={fun}>点我触发异步操作</button> 
    </div>
  )
}
export default connect()(User)

2.编写effects异步触发器


export default {
    namespace: 'userm',//命名空间---就是给当前这个模块起个名字(唯一的)
    state: {
        name:"我是user模块中的数据"
    },//存放数据的
    subscriptions: {//类似于一个监听  在里面可以绑定很多个监听的方案
    
    },
    effects: {//类似于vuex的actions  进行异步触发的  effects的函数必须是一个Generator函数
        *LINK(){
            console.log("我被触发了");
        }
    },
    reducers: {//  修改上面的state的地方
     
    },
  };

3.设置请求

在dva中默认已经帮助我们封装好了异步请求 我们不需要单独去配置与下载 在service文件夹下新建文件 创建请求

import request from '../utils/request';

export function query() {
  return request('http://localhost:8888/userlist/getlink');
}

4.把写好的请求在effects中使用

// 1.引用我们刚才写好的请求
import {query} from "../services/userlink.js"
export default {
    namespace: 'userm',
    state: {
        name:"我是user模块中的数据"
    },
    subscriptions: {
    
    },
    effects: {
        // 2.使用异步请求
        // call 调用异步操作 并且得到成功的值
        *LINK({payload},{put,call}){
            console.log("我被触发了");
            // 下一步 使用call来获取成功的返回值
          let data= yield call(query
        }
    },
    reducers: {
     
    },
  };
  

5.把请求成功的数据复制给state方便组件使用( 先要交给reducers )

// 1.引用我们刚才写好的请求
import {query} from "../services/userlink.js"
export default {
    namespace: 'userm',
    state: {
        name:"我是user模块中的数据"
    },
    subscriptions: {
    
    },
    effects: {
        // 2.使用异步请求
        // call 调用异步操作 并且得到成功的值
        // put把effects中触发reducers
        *LINK({payload},{put,call}){
            console.log("我被触发了");
            // 下一步 使用call来获取成功的返回值
          let data= yield call(query

        //   把请求来的数据通过reducers修改给state
        // 下一步  通过put触发reducers
            yield put({type:"UP_NAME",data})

        }
    },
    reducers: {
     
    },
  };

6编写对应的reduicers

// 1.引用我们刚才写好的请求
import {query} from "../services/userlink.js"
export default {
    namespace: 'userm',
    state: {
        name:"我是user模块中的数据"
    },
    subscriptions: {
    },
    effects: {
        // 2.使用异步请求
        // call 调用异步操作 并且得到成功的值
        // put把effects中触发reducers
        *LINK({payload},{put,call}){
            console.log("我被触发了");
            // 下一步 使用call来获取成功的返回值
          let data= yield call(query

        //   把请求来的数据通过reducers修改给state
        // 下一步  通过put触发reducers
            yield put({type:"UP_NAME",data})

        }
    },
    reducers: {
        // 设置修改
        UP_NAME(state,payload){
            return {...state,name:payload.data}
        }
    },
  };

7 在页面读取数据

import Topbar from "../components/topbar.jsx"
import {connect} from "dva"
 function User(props) {
    let fun=()=>{
        // 触发effects进行异步操作
        // props.dispatch({type:"你要调用的模块命名空间名字/effect的名字"})
        props.dispatch({type:"userm/LINK"})    
    }
  return (
    <div>
        <Topbar></Topbar>
        user---{props.state.userm.name}
        
       <button onClick={fun}>点我触发异步操作</button> 
    </div>
  )
}
export default connect(state=>({state}))(User)

8 在运行之后出现了跨域问题 添加跨域 项目的根路径下有一个webpackrc的文件中添加跨域

{
    "proxy":{
        "/api":{
             "target":"http://localhost:8888",
             "changeOrigin":true,
             "pathRewrite":{
               "^/api":"/"
             }
        }
    }
}

9.修改请求地址为/api

import request from '../utils/request';

export function query() {
  return request('/api/userlist/getlink');
}

10.修改下请求的传递数据

// 1.引用我们刚才写好的请求
import {query} from "../services/userlink.js"
export default {
    namespace: 'userm',
    state: {
        name:"我是user模块中的数据"
    },
    subscriptions: {
    
    },
    effects: {
        // 2.使用异步请求
        // call 调用异步操作 并且得到成功的值
        // put把effects中触发reducers
        *LINK({payload},{put,call}){
            console.log("我被触发了");
            // 下一步 使用call来获取成功的返回值
          let data= yield call(query)
          console.log(data.data.msg);

        //   把请求来的数据通过reducers修改给state
        // 下一步  通过put触发reducers
            yield put({type:"UP_NAME",data:data.data.msg})

        }
    },
    reducers: {
        // 设置修改
        UP_NAME(state,payload){
            return {...state,name:payload.data}
        }
    },
  };
  

subscriptions 设置一个监听

可以在里面设置一些监听函数 必须页面修改了 鼠标移动了等等等

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_44930306/article/details/127289194

智能推荐

Oracle12c超详细安装教程_oracle12c安装及配置-程序员宅基地

文章浏览阅读1.6w次,点赞17次,收藏91次。最好选择一个相对干净的系统进行安装,也就是没有安装各种杂七杂八的软件的系统,否则极有可能在安装过程中出现一些报错,接下来正式开始。_oracle12c安装及配置

ABAP替换字符串中的千分位字符_替换千分位符号-程序员宅基地

文章浏览阅读1.4k次。处理逻辑:abap小数点有两种:逗号(,)跟点号(.),千分位字符也分为这两种,本方法只为去掉千分位字符1、查找点号跟逗号的个数2、若点号个数大于1且逗号个数也大于1,则该数字为错误类型数字,退出程序3、若点号个数大于1,则用空格替换到字符串中的所有点号,然后去空格4、若逗号个数大于1,则用空格替换掉字符串中的所有逗号,然后去空格5、若点号个数 = 逗号个数 = 1:_替换千分位符号

java事件监听器_java监听器-程序员宅基地

文章浏览阅读1w次,点赞22次,收藏172次。1.动作事件监听器动作事件(ActionEvent)监听器是Swing中比较常用的事件监听器,很组件的动作都会使用它监听,如按钮单击,下表描述了动作事件监听器的接口与事件源。事件名称 事件源 监听接口 添加或删除相应类型监听器的方法 ActionEvent JButton、JList、JTextField等 ActionListener addAct..._java监听器

OpenLayers基础教程——要素的编辑_openlayers 选中编辑-程序员宅基地

文章浏览阅读1.9k次,点赞3次,收藏12次。1、前言在OpenLayers中,要素的编辑主要使用ol.interaction.Select和ol.interaction.Modify配合实现,下面开始介绍。2、编辑要素编辑功能的实现很简答,ol.interaction.Select负责选择要素,ol.interaction.Modify对被选择的要素进行编辑,代码如下:<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head> _openlayers 选中编辑

Android Material Design控件使用(二)_android 使用 material desingn ui 控件-程序员宅基地

文章浏览阅读790次,点赞3次,收藏2次。Android Material Design控件使用(二)_android 使用 material desingn ui 控件

servlet 异常处理_Servlet异常和错误处理示例教程-程序员宅基地

文章浏览阅读4.5k次,点赞3次,收藏4次。servlet异常处理Today we will look into Servlet Exception and Error Handling. Sometime back I wrote a post about Exception Handling in Java but when it comes to web application, we need more than normal ex..._servletexception

随便推点

spring常见面试题_spring注解面试题-程序员宅基地

文章浏览阅读383次。spring常见面试题1.spring中的拦截器和过滤器介绍2.说一下spring中的IOC3.spring中的异常处理4.jdk动态代理和cglib代理5.spring bean的生命周期6.spring IOC原理7.BeanFactory和FactoryBean的区别8.spring解决循环依赖9.spring默认为单例模式为什么10.AspectJ和spring aop代理区别11.spring的bean是线程安全的么12.spring的优点13.spring中的设计模式_spring注解面试题

c++十大排序——堆排序_c++堆排序-程序员宅基地

文章浏览阅读8.5k次,点赞19次,收藏109次。1、堆排序堆排序采用堆的这种数据结构,堆首先是一颗完全二叉树。堆又分为大顶堆和小顶堆大顶堆就是父节点数值大于等于左右节点数值小顶堆是父节点数值小于等于左右节点数值下标为i的节点的父节点下表为:(i-1)/2下标为i的节点的左孩子下表为:i*2+1下标为i的节点的右孩子下表为:i*2-1#include<iostream>using namespace std;void sw(int &a,int &b) { int temp _c++堆排序

Openstack 从云硬盘(卷)中创建虚拟机_openstack volume create-程序员宅基地

文章浏览阅读1.8k次。Openstack 从云硬盘(卷)中创建虚拟机_openstack volume create

redis入门(三)_redis slot open-程序员宅基地

文章浏览阅读6.4k次。文章目录@[toc]redis入门(三)目录前言事务原理Lua脚本安装脚本命令EVALEVALSHAlua和redis互操作SCRIPT EXISTSSCRIPT FLUSHSCRIPT KILL脚本复制集群搭建工具redis-trib.rbredis官方集群搭建集群横向扩展故障转移redis管理参考文档redis入门(三)目录redis入门(一)redis入门(二)redis入门(三)..._redis slot open

idea生成SpringBoot项目端口号的修改_idea如何设置8080端口-程序员宅基地

文章浏览阅读2.4k次。idea生成SpringBoot项目端口号的修改第一次使用idea,在生成SpringBoot项目的时候,提示端口8080被占用,这个时候有两个办法:1、修改端口号(推荐)①如果是.yml配置文件,添加server:port:8888,格式和下图相同,需要注意的一点是,server必须和spring同列,否则无效②如果是properties文件,配置文件中添加 server.port=88..._idea如何设置8080端口

编程语言和操作系统是什么关系?编程语言如何被计算机执行的?驱动程序的理解?_操作系统和编程语言的关系-程序员宅基地

文章浏览阅读2.2k次。我们平常所提到的计算机的内存指的是动态内存(即DRAM),动态内存中所谓的“动态”,指的是当我们将数据写入DRAM后,经过一段时间,数据会丢失,因此需要一个额外设电路进行内存刷新操作。但时间一长,代表1的电容会放电,代表0的电容会吸收电荷,这就是数据丢失的原因。我们都知道,中间层是为了提供抽象转换而存在的,而这套叫做操作系统的中间层,定义了一套规则,使得后续的可执行程序能够更容易的被运行起来,而且能更容易的利用各种硬件(显示,键盘等等),能够调用一些库来消除不同的程序间重复的运行逻辑。_操作系统和编程语言的关系

推荐文章

热门文章

相关标签