• 前后端分离——前端项目使用Mock.js 模拟数据


    一、简单介绍一下Mock.js 

    众所周知Mock.js因为两个重要的特性风靡前端:

    • 数据类型丰富
      支持生成随机的文本、数字、布尔值、日期、邮箱、链接、图片、颜色等。(详情见官网

    • 拦截 Ajax 请求
      不需要修改既有代码,就可以拦截 Ajax 请求,返回模拟的响应数据。安全又便捷

    文章会用到的API(也是Mock经常使用的API):

      • Mock.mock(url, type, data)
    参数名参数需求参数描述例子
    url 可选: URL 字符串或 URL 正则 拦截请求的地址 /mock
    type 可选 拦截Ajax类型 GET、POST
    template 可选: 可以是对象或字符串 生成数据的模板 {'data|1-10':['mock'] }'@EMAIL'

    template可能有点难理解,我们试几个例子就一目了然了!

    //类型1: 名字|规则: 内容
    Mock.mock({'data|1-4': '哑巴'})
    
    //生成1-4个'哑巴'字符串
    {
        data: "哑巴哑巴哑巴"
        
    }
    
    //类型2: Mock自带模板
    Mock.mock('@province')
    
    //随机生成一个省份
    "上海"

    更多测试实例可以到:http://mockjs.com/examples.html上查看。

    也可以亲自在网站的console里测试,非常方便:

    二、如何高效地使用Mock.js

    针对不同情况,罗列了以下几种可能会使用到的方式:

    • 直接创建使用
      1) 直接在需要Mock数据的js文件使用
      2) 创建一个js/json文件,导入使用

    • 优雅地搭配node
      1) 通过node开启Mock服务, 可加入到package.json命令里

    上面两种方法区别蛮大的:

    1. 直接创建的Mock数据, 在控制台的netWork是无法看到的.而通过服务开启的Mock,在控制台是真真切切看得到拦截的!

    2. 对于要上线的项目, 直接创建(导入)Mock数据还会导致一个大的麻烦!当你开始调用真正后端接口的时候, 你不得不一个个删除创建的数据(即使你统一在一个文件创建,但也要一个个注释掉导入的地方)。 但是如果你用node服务,就避免了这个问题了。因为你需要用Mock数据的时候,只需要开启它的服务,而不需要导入

    下面我在一个小项目(React + Antd)上测试Mock:

    2.1直接创建使用

    let dataSource = Mock.mock({
        'dataSource|5':[{
            'key|+1': 1,
            'mockTitle|1':['哑巴', 'Butter-fly', '肆无忌惮', '摩天大楼', '初学者'],
            'mockContent|1': ['你翻译不了我的声响', '数码宝贝主题曲', '摩天大楼太稀有', '像海浪撞破了山丘'],
            'mockAction|1': ['下载', '试听', '喜欢']
        }]
    })
    
    //为了提高阅读效率, columns我就不放出来啦!
    
    <Table
        style={{marginTop: 10}}
        columns={columns}
        dataSource={dataSource}
    />

    其中,'mockTitle|1':['哑巴', 'Butter-fly', '肆无忌惮', '摩天大楼', '初学者']的含义为['哑巴', 'Butter-fly', '肆无忌惮', '摩天大楼', '初学者']数组中选择一个值

    详情请参考:语法规范

    我们看一下输出的Table:

    但对于追求完美的我们肯定想要代码更规范, 于是我们把它统一放到一个/mock/api.js文件中, 并尝试给它添加一个URL!

    //api.js
    import Mock from 'mockjs'
    
    const url = {
        tableDataOne: 'http://20181024Mock.com/mode1/tableDataOne',
        tableDataTwo: 'http://20181024Mock.com/mode1/tableDataTwo',
        tableDataThi: 'http://20181024Mock.com/mode1/tableDataThi',
    }
    module.exports = [
        Mock.mock(url.tableDataOne, {
            'dataSource|5':[{
                'key|+1': 1,
                'mockTitle|1':['哑巴', 'Butter-fly', '肆无忌惮', '摩天大楼', '初学者'],
                'mockContent|1': ['你翻译不了我的声响', '数码宝贝主题曲', '摩天大楼太稀有', '像海浪撞破了山丘'],
                'mockAction|1': ['下载', '试听', '喜欢']
            }]
        })
    ]

    我们在去组件中引入api.js, 然后用axios请求它!

    //TableComp.js
    /*
    * 我这里去掉了多余的import,例如antd、react等等
    * 只截取了组件的主要学习部分
    */
    
    import axios from 'axios'
    
    //按需引入api文件, 但后面会导致删除麻烦的问题.
    import '../../../../../../mock/mode1/api'
    
    componentDidMount(){
        const that = this;  
        axios.get('http://20181022Mock.com/mode1/tableDataOne').then((res) => {
            if(res.status == 200){
                that.setState({
                    dataSource: res.data.dataSource
                })
            }
        })
    }
    
    render(){
        const { dataSource } = this.state;
        
        return(
            <Table
                style={{marginTop: 10}}
                columns={columns}
                dataSource={dataSource}
            />
        )
    }

    不出乎意料, 应该也是可以拿到数据, 但是netWork里面是找不到这个请求的, 因为这是一个假的ajax!

    这样虽然解决了代码统一处理/规范的问题, 但是每次使用都需要引入的麻烦并没有解决。 下面我们看如果通过搭配node服务解决这个问题.

    2.2优雅地搭配node来使用mock.js

    既然我们要伪造一个真的后台, 那么当然需要用node来启动服务, 那么我们就创建一个MockServer.js文件,当作是我们的入口.

    和以前创建node服务一样即可!(这里我偷懒用express框架,koa也是一样的道理)

    let express = require('express');   //引入express
    let Mock = require('mockjs');       //引入mock
    
    let app = express();        //实例化express
    
    app.use('/mode2/DataOne',function(req, res){
        res.json(Mock.mock({
            'status': 200,
            'dataSource|1-9':[{
                'key|+1': 1,
                'mockTitle|1':['肆无忌惮'],
                'mockContent|1': ['角色精湛主题略荒诞', '理由太短 是让人不安', '疑信参半 却无比期盼', '你的惯犯 圆满', '别让纠缠 显得 孤单'],
                'mockAction|1': ['下载', '试听', '喜欢']
            }]
        }))
    })
    
    app.listen('8090', () => {
        console.log('监听端口 8090')
    })

    只需要以上几个步骤就可以完成了!

      1. 实例化express对象、引入mock模块
      2. (加入请求头,解决跨域)
      3. 通过express挂载一个请求(use、get...),并返回mock数据
      4. 暴露端口,开启服务!

    大家可能注意到了第二点我还没实现.不过我们先不考虑跨域问题, 运行一下看看会出现什么情况。(存在跨域问题是必然的, 因为都不是同一个端口号!)

    果然, 跨域问题出来了:

    把请求头配置加上去吧(复制即可):

    app.use(function(req, res, next) {
        res.header("Access-Control-Allow-Origin", "*");
        res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
        res.header("Access-Control-Allow-Headers", "X-Requested-With");
        res.header('Access-Control-Allow-Headers', 'Content-Type');
        next();
    });

    跨域问题就顺利解决了!

    这样一来我们就解决了导入带来的麻烦了!如果不想进入MockServer.js所在的文件夹里启动服务, 可以在package.json中配置命令

    //package.json
    {
        ...
        "scripts": {
            "start": "node ./bin/www",
            "build": "webpack --progress --watch --color",
            "mock": "node ./mock/mode2/mockServer"
          },
        ...
    }

    然后我们像启动项目一样, 在根路径npm run mock即可!

    比较坑爹的是, 这样配置并不存在自动更新功能, 所以我们每次更改了MockServer.js还要command + c 杀掉这个进程, 重启服务生效。

    虽然实际项目使用Mock的这种方式蛮多的, 但是其中复杂地多, 比如Mock生成数据的规则会统一放到一个rule.js中. 更多的便捷配置和用法还是需要你去学习别的项目是怎么运作的!

    转自:https://www.cnblogs.com/soyxiaobi/p/9846057.html

    参考:https://blog.csdn.net/weixin_45000381/article/details/98234684

  • 相关阅读:
    将 expression 转换为数据类型 int 时发生算术溢出
    将博客搬至CSDN
    山东省滕州市木石镇化石沟村QQ群116528924
    未能加载文件或程序集 Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad
    sql server 怎么实现mysql中group_concat,列转行,列用分隔符拼接字符串
    sql server 条件 not in (null)总是false
    SCRIPT7002: XMLHttpRequest: 网络错误 0x2ef3, 由于出现错误 00002ef3 而导致此项操作无法完成,浏览器中的Keep-Alive
    2015年总结之什么叫软件开发?
    XSD(XML Schema Definition)用法实例介绍以及C#使用xsd文件验证XML格式
    XML组成结构以及C#通过DTD验证规范性
  • 原文地址:https://www.cnblogs.com/vickylinj/p/12336235.html
Copyright © 2020-2023  润新知