本篇文章,主要介绍前端mock数据的几种方式,基本解决所有情况,所有数据结构需求
小问答看看是否了解:
下面(创建了三个vue文件,json.vue mock.vue node.vue,来写这三种情况的例子)跟着思路,从易到难,让我们一起来一一解决,如有问题欢迎讨论指正(本篇将使用一个老的vue2.0的项目来写demo,大家可自行找个新技术新项目去写如有不懂可去主页看其他文章,里面都有介绍)
这个问题应该是个前端都会接触,没有接口文档,没有字段说明,我们也要开发的,当然时间充足,摸鱼到接口出来 在写也行,哈哈哈。言归正传,下面提供三种mock写法 ( 以下demo将写在json.vue里 ) :
比如一个下拉选选项,一个简单的表格,这种情况,我们可以直接写死在页面里
json 死数据
这个是最常用的,直接写
优点:简单,快
缺点:如果项目页面多了,页面data数据多了,里面又有表格,又有下拉选,又有图表,一个data几百行,改起来不好找,看起来不好看
这种情况可以把数据,单独抽出一个json文件或者js文件,暴露出去,然后在要用的vue文件组件里去引用
在页面同级新建一个文件专门用来放数据,如果有人提供json数据就用json文件,如果没有推荐用js文件
json 死数据
json 死数据
最终效果都是正常的
优点:vue文件看起来简洁,多个地方使用时,直接引用,使用方便,修改方便
缺点:和第一个一样都没有走http请求,没有请求加载过程,当然我们可以加个loading,写个定时器来模拟,但是没办法走请求拦截,响应
这个项目是这样的
http接口请求user.js文件
getJsonList() {
return request.get('/static/jsonData/json.json')
},
json.vue 文件
json 死数据
效果
发出了一个get请求,json数据正常返回,走了项目的请求封装,所以全局封装的加载动画,请求头,请求拦截,响应拦截等,都走了,相当于和后端联调了一个完整的接口请求
优点:和后端接口联调保持一致,有一个完整的请求
缺点:不适合单个页面,小数据量使用,适合没后端数据,只做前端展示的静态页面,适合产品或者有关人员给你了大量的json数据,做展示
这种情况下,第一种情况的三种情况下也能解决,不过数据是写死的,我们要手动去录入大量的数据,所以我们采用mock的形式来解决,既做到了接口请求,又解放了数据录入的体力活,还能使数据随机生成,下面我们来实现(以下demo将写在mock.vue里)mock文档移步这里
npm install mockjs -D
或者
cnpm install mockjs -D
当然用yarn也行
为了后面继续扩展,建议一个模块一个文件夹,最后index.js里统一引入即可
import Mock from 'mockjs'
import base from '../../http/base'
const dataList = Mock.mock({
'list|4-10': [{
date: '@date',
name: '@name',
address: '@county(true)'
}]
})
Mock.mock(`${base.BASE_URl}/page4/mock/dataList`, 'get', () => {
return dataList
})
引入mock,base是自己项目的全局接口配置,后面写的就是接口名称,按照自己的需求语义化写即可,最后把mock的数据 return 出去即可,list|4-10 代表返回的数据结构list数组,内容4-10条,@date @name 啥的语法规范可以看文档说明,还可以写正则,mock自己想要的数据格式
import Mock from 'mockjs'
import './page4mock'
// 设置全局延时
Mock.setup({
timeout: '200-400'
})
引入mock的数据 设置全局加载延时,模拟加载
import './mock'
同上的解决方式,在自己项目封装的请求里添加接口请求
本项目是
http接口请求user.js文件
getMockList() {
return request.get(`${base.BASE_URl}${'/page4/mock/dataList'}`)
},
这里的接口名称,就是上面mock/page4Mock/index.js 文件里写的那个接口名称
mock 随机数据 刷新可变
可以安装json5 这样就可以在json文件夹里写注释啥的了,入口呢也可以加个判断,然后在全局定义变量,去判断接口走mock还是走后端,具体可自行查看文档和其他文章,本文章只是写了一个简单的例子
优点:省去手动录入的体力活,数据随机,指定字段名,后续有正式接口数据时,直接把main.js入口注释即可
缺点:一般项目用不到,有点小麻烦,还要安装依赖啥的
提示:最后有正式接口时,把main.js的入口给注释掉
这种比较麻烦点,要自己搭个 nodejs后端服务器,相当于咱自己前后端都写了,解决的需求就是,项目临时发到线上展示了,里面的数据要修改,如果在重新修改项目在部署难免有点耽搁,但是有没有后端人员的支持,所以我们自己来,下面主要用到nodejs,文档请移步,现在收费了,可以看凑和看下低版本的免费,有钱的话可以充会员,哈哈哈
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时,它让javascript可以开发后端程序,实现几乎其他后端语言实现的所有功能!这意味着我们只需要掌握javaScript一门语言就能够进行全栈开发啦,激动不。
具体由来,特性,语法等,可自行百度,这里不做过多介绍,只做简单的铺垫
打开一个新的编辑器窗口,因为我们要另起一个项目
node -v 查看是否安装成功
然后我看下他是怎么运行的,新建一个空的文件夹本文是 my_nodejs 来记录咱们,迈向后端的第一步,在里面新建一个main.js
const name = '我是H'
console.log(name)
然后执行
node mian.js
可以看到,有打印出来
然后我们每次修改main.js,发现还是要在执行一下 才能看到结果
显然不行,所以我们安装下nodemon插件,来帮我们自动执行
npm i nodemon -g
之后使用 nodemon 来运行 main.js
nodemon mian.js
当我们在修改main.js ctrl+s 保存的时候,nodemon 可以自动帮我们执行
// 引入http模块
const http = require("http");
// 定义端口和请求地址,这个可以随便写
const port = 3000;
const hostname = "127.0.0.1";
// 创建服务器
const server = http.createServer();
server.on("request", (req, res) => {
// req:接受浏览器传的参数
// res:返回渲染的内容
res.write('{name:"H"}');
res.write('{"age":18}');
res.write("你好");
res.end();
})
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`, '我启动了')
})
注意
write
方法传递内容,可以调用多次,内容必须是字符串格式
最后必须调用end
方法告诉请求的调用者我们响应结束了
也可以直接在end
方法内传递内容,但end
方法只能调用一次
浏览器打开127.0.0.1:3000 就可以看到我们的输出结果了,但是中文乱码
res.writeHead(200, {
"Content-Type": "application/json"
});
当然也可以单独设置
// 设置相应头信息
res.setHeader("Content-Type", "application/json");
// 设置状态码
res.statusCode = 200;
// 传递html内容
nodejs文档里都有写,然后回到浏览器刷新,完成
这个时候是不是就有灵感了,我那个项目可以去请求这个服务,不就可以访问这里面的数据了吗,没错,是这样的,我们可以先试一下
加个请求,浏览器打开
首页
我是fetch请求,我叫:
然后main.js请求头里配置跨域,内容也只要一个res.end(‘{“name”:“H”}’);
"Access-Control-Allow-Origin": "*",
index.html 右键用live server打开
回到浏览器,点击按钮
但问题来了,不可能一个服务只能用一个接口,请求一个数据吧,所以下面我们在来扩展下路由
实现http://127.0.0.1:3000/XXX 访问对应XXX的数据
这个时候我们要知道前端路由,url是什么,所以用到 new URL
先看文档,new URL ,里面有详细介绍
const myUrl = new URL(req.url, `http://${hostname}:${port}/`);
console.log(myUrl);
可以看到 发了两个请求 一个是我们要的 一个是静态ico,所以我们可以根据 pathname来区分路由,相应的参数目前我们不用
扩展:直接get可以获取相应参数
console.log(myUrl.get("id")); // 123
然后我们在修改下main.js
switch (myUrl) {
case '/home':
res.end('{ "page": "我是home" }');
return
case '/about':
res.end('{ "page": "我是about" }');
return;
default:
return res.end('{ "page": "404" }');
}
对应的index.html 也可以根据路由稍作修改,因为刚刚接口改了,没有现在访问就是404 也没有name属性,会变成undefined,至此 nodejs 先铺垫至此,进入主题
const notFind = JSON.stringify(require('../static/404.json'))
const dataList = JSON.stringify(require('../static/admin3/list.json'))
function renderContent(url) {
switch (url) {
case '/page4/node/dataList':
return dataList;
default:
return notFind
}
}
exports.renderContent = renderContent;
exports.routerList = ["/page4/node/dataList", "/home"];
为了后期加路由,单独抽出了一个,用来写路由判断
renderStatus.js
const routerList = require("./renderContent.js");
function renderStatus(url) {
return routerList.routerList.includes(url) ? 200 : 404;
}
module.exports = {
renderStatus,
};
用来判断请求http 状态码,如果存在就是200,否则404
static用来存放数据
{
"title": "简单列表页",
"success": true,
"status": 200,
"data": {
"tableColumn": [
{
"label": "日期",
"prop": "date"
},
{
"label": "姓名",
"prop": "name"
},
{
"label": "地址",
"prop": "address"
}
],
"tableData": [
{
"date": "2016-05-02",
"name": "王小虎111",
"address": "上海市普陀区金沙江路 1516 弄"
},
{
"date": "2016-05-04",
"name": "王小虎",
"address": "上海市普陀区金沙江路 1517 弄"
},
{
"date": "2016-05-01",
"name": "王小虎",
"address": "上海市普陀区金沙江路 1518 弄"
}
]
}
}
{
"name": "404",
"success": false,
"status": 404,
"message": "页面不存在"
}
const http = require('http');
const port = 3000;
const hostname = "127.0.0.1";
const {
renderContent
} = require("./service/renderContent");
const {
renderStatus
} = require("./service/renderStatus");
const server = http.createServer();
server.on("request", (req, res) => {
if (req.url === "/favicon.ico") return
const myUrl = new URL(req.url, `http://${hostname}:${port}/`).pathname;
res.writeHead(renderStatus(myUrl), {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
});
res.end(renderContent(myUrl));
})
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`)
})
提示:/page4/node/dataList' 是我们node项目renderContent.js里写的
getNodeList() {
return request.get(`${base.BASE_URl}${'/page4/node/dataList'}`)
},
组件封装可忽略,重点看请求,想看请移步另一篇文章
3、vue项目 添加跨域,重启项目,不然访问不通
这个target 就是我们node项目main.js里的,hostname和port,保持一致即可
4、打开浏览器vue项目
接口504,因为我们node服务没启动,打开node项目执行
nodemon main.js
在回到浏览器刷新vue项目
OK,接口请求成功
这个时候 我们在node项目里,修改list.json 的值
ctrl s ,再回到 vue项目里刷新看下
npm run build
没啥问题啊,正常,然后我们部署到外网 github上 或者自己服务器上,github pages部署请移步/
ok,结束
nodejs里的东西很多,后面还可以继续扩展,node项目github已附上,想玩的可以继续玩。
前端vue项目就不贴了,一个几年前很老的项目,东西都太老,你们用自己的新项目就行
vue前端项目预览地址
nodejs 官方文档
mockjs 官方文档
nodejs服务项目github地址