初始化
//main.js中
import "@/network/fake-message/index.js" //全局文件中引入虚假数据
//@/network/fake-message/index.js
//创建伪数据
import Mock from 'mockjs'
import { Random } from 'mockjs'
//获取商品列表
Mock.mock(/api\/goodlist/,'get',{
status:200,
message:'获取商品列表成功',
"string|1-8":"a"
})
//注意每次修改这部分代码的时候,需要重新运行程序
//network/request/request.js
//axios请求的封装
import axios from "axios"
export function request(config){
const instance=axios.create({
baseURL:'http://localhost:8080',
timeout:100000
})
return instance(config)
}
数据规范
数据模板定义规范
每个属性由三部分组成:属性名、生成规则、属性值
'name|rule':Value
生成规则的含义需要依赖属性值的类型才能确定
举例
属性值是字符串
- ’name|min-max’:string
通过重复string生成一个字符串,并由重复次数的规则 - ‘name|count’:string
数据占位符定义规范
占位符只是在属性值字符串中占个位置,并不会出现在最终的属性值中
@占位符
@占位符(参数 [, 参数])
- 占位符引用的是Mock.Random中的方法
- 可以通过 Mock.Random.extend() 来扩展自定义占位符
Random.extend({
constellation: function(date) {
var constellations = ['白羊座', '双子座', '巨蟹座', '狮子座', '天秤座', '天蝎座', '射手座', '水瓶座']
return this.pick(constellations)
}
})
Random.constellation()
// => "水瓶座"
Mock.mock('@CONSTELLATION')
// => "天蝎座"
Mock.mock({
constellation: '@CONSTELLATION'
})
// => { constellation: "射手座" }
Mock.mock
Mock.mock( rurl?, rtype?, template|function( options ) ) 用来生成模拟数据
记录数据魔板,当拦截到匹配rurl和rtype的Ajax请求时,将根据数据魔板template或者执行函数生成模拟数据,并作为响应数据的返回
rurl
表示需要拦截的UL,可以是URL字符串或者URL正则//domain/list.json/、‘/domian/list.json’
rtype
表示需要拦截的Ajax请求类型,例如 GET、POST、PUT、DELETE 等。
template
表示数据魔板,可以是对象或者字符串。例如 { ‘data|1-10’:[{}] }、‘@EMAIL’。
function(options)
表示用于生成响应数据的函数
options
指向本次请求的Ajax选项集,含有url、type和body三个属性
常用语法举例
生成字符串
生成指定次数字符串
const data = Mock.mock({
"string | 3": "aa" // 生成"aaaaaa"
})
生成指定范围长度字符串
const data = Mock.mock({
"string | 1-8": "a" // 随机生成1-8个长度的"a"
})
生成文本
生成一个随机字符串
const data = Mock.mock({
"string": "@cword"
})
在@符号的后面以c开头的一般表示的是中文,如上方的cword就表示一个随机的汉字,如果是word的话就是一个随机的英文单词。
生成指定长度和范围
const data = Mock.mock({
string: "@cword(1)"
str : "@cword(10,15)"
})
生成标题和句子
生成标题和句子
const data = Mock.mock({
title: "@ctitle",
sentence: "@csentence"
})
Mock.mock(/api\/goodlist/,'get',{
status:200,
message:'获取商品列表成功',
data
})
生成指定长度的标题和句子
const data = Mock.mock({
title: "@ctitle(8)"
sentence: "@csentence(50)"
})
生成指定范围的标题和句子
const data = Mock.mock({
title: "@ctitle(5,8)"
sentence: "@csentence(50,100)"
})
举例-实现基本get、post和根据id发请求
//创建伪数据
import Mock from 'mockjs'
import { Random } from 'mockjs'
//案例test
Random.extend({
fruit:function(){
const arr=['榴莲','波罗蜜', '椰子', '苹果', '菠萝', '释迦']
return this.pick(arr)
}
})
//获取商品列表
Mock.mock(/api\/goodlist/,'get',{
status:200,
message:'获取商品列表成功',
'data|5-10': [
{
id: '@increment(1)', // 自增的Id值
// 'id|+1': 0, // 这也是在模拟一个自增长的 Id 值
name: '@cword(2, 8)', // 随机生成中文字符串
price: '@natural(2, 10)', // 自然数
count: '@natural(100, 999)',
img: '@dataImage(78x78)' // 指定宽高图片
}
]
})
//添加商品
Mock.mock(/api\/addgoods/, 'post', function(option) {
// 这里的 option 是请求相关的参数
console.log(option)
// 如果需要在返回的对象中再使用mock的语法,则需要再使用Mock.mock
return Mock.mock({
status: 200,
message: '@cword(2,5)'
})
})
//根据id获取商品信息---常用
Mock.mock(/api\/getgoods/,'get',function(option){
console.log(option)
//通过正则的.exec()函数,从字符串中提取需要的数据
//const res=/\/api\/getgoods/(/\d+/)/.exec(option.url) //不知道为什么,在使用正则匹配的时候会报错
//也可以通过字符串的split方法获取id
const urlId = option.url.split('/')[3]
return Mock.mock({
data:{
id:urlId,
name:'@fruit()',
price:2,
count:199,
img:'@dataImage(78x78)'
},
status:200,
message:'获取商品成功!'
})
})
<template>
<div class="left-nav">
<button @click="getGoodsList">获取商品列表</button>
<button @click="addGoods">添加商品</button>
<button @click="getGoodsById(9)">根据Id获取商品信息</button>
</div>
</template>
<script>
import {request} from 'network/request/request.js'
export default {
data() {
return {
};
},
methods: {
getGoodsList(){
request({
url:'/api/goodlist',
method:'get'
}).then(res=>{console.log(res);})
},
async addGoods(){
//添加商品数据,开发中是需要获取用户输入的值进行添加
const {data:res}=await request({
url:'/api/addgoods',
method:'post',
data:{
name: '菠萝',
price: 8,
count: 550,
img: ''}
})
console.log(res); //添加商品成功的返回值
},
async getGoodsById(id){
const {data:res}=await request({
url:`/api/getgoods/${id}`,
method:'get'
})
console.log(res)
}
},
};
</script>
例子-对新闻列表实现增删改查
加上分页功能以及请求数据的参数不同哈游删除和添加的方式不同
const {newsList}=Mock.mock({
"newsList|75":[
{
id:"@increment",//随机生成一个递增的id
title:"@ctitle()",
content:"@cparagraph(5,10)",
img_url: "@image('3*3','#FF83FA','#FCFCFC','png','mono')",//随机生成一个图片
add_time: "@date(yyyy-MM-dd hh:mm:ss)",
}
]
})
//从url中获取query参数https://juejin.cn/user/4433690702123534?id=1&name=rocky
var getQuery=(url,name)=>{
console.log(url,name);
//判断是否有query参数
const index=url.indexOf('?')
if(index!==-1){
//截取?后面字符串再将其以&分割成数组:['id=1','name=rocky']
const queryStrArr=url.substr(index+1).split('&')
for(var i=0;i<queryStrArr.length;i++){
//再对数组中的每一项以=进行分割成数组:[id,1],[name,rocky]
const itemArr=queryStrArr[i].split("=")
if(itemArr[0]==name){
return itemArr[1]
}
}
}
return name
}
//获取新闻列表
// 因为具体的url形式类似为/api/get/news?pageinde1&pagesize=10,所以我们这里使用正则去匹配
Mock.mock(/api\/get\/news/,'get',function(options){
// 获取分页相关参数pageindex,pagesize
const pageindex=getQuery(options.url,'pageindex')
const pagesize=getQuery(options.url,'pagesize')
console.log(pageindex,pagesize);
//获取数据的起始位置、结束位置和总页数
// pageindex:1 pagesize:10 返回0-9条数据 2-10(10-19) 3-10(20-29)
const start=(pageindex-1)*pagesize
const end=pagesize*pageindex
const totalPage=Math.ceil(newsList.length/pagesize)
const list=pageindex>totalPage?[]:newsList.slice(start,end)
return{
status:200,
message:'获取新闻成功',
list:list,
total:totalPage
}
})
//添加新闻数据
Mock.mock(/api\/add\/news/,'post',function(options){
const body=JSON.parse(options.body)
console.log(body)
newsList.push(//网之前的newslist中追加数据
Mock.mock({
id:"@increment",
title:body.title,
content:body.content,
img_url: "@image('3*3','#FF83FA','#FCFCFC','png','mono')",
add_time: "@date(yyyy-MM-dd hh:mm:ss)",
}))
return {
status:200,
message:'添加成功',
list:newsList,
total:newsList.length
}
})
//删除新闻
Mock.mock(/api\/delete\/news/,'post',function(options){
const body=JSON.parse(options.body)
const index=newsList.findIndex(item=>{
return item.id===body.id
})
newsList.splice(index,1)
return {
status:200,
message:"删除成功",
list:newsList,
total:newsList.length
}
})
<template>
<div>
<div class="add">
<input type="text" v-model="title" placeholder="输入标题" />
<input type="text" v-model="content" placeholder="输入内容" />
<button @click="add">添加</button>
</div>
<div class="news_list">
<table>
<tr v-for="item in list" :key="item.id">
<td><img :src="item.img_url" alt="" /></td>
<td>{{ item.title }}</td>
<td>{{ item.content }}</td>
<td>{{ item.add_time }}</td>
<td>
<button class="remove" @click="remove(item.id)">删除</button>
</td>
</tr>
</table>
</div>
<div class="pages">
<button @click="prevPage">上一页</button>
<button @click="nextPage">下一页</button>
</div>
</div>
</template>
<script>
import {request} from 'network/request/request.js'
export default {
data() {
return {
title: "",
content: "",
list: [],
pageindex: 1,
content: "",
};
},
created(){
this.getnewsList()
},
methods: {
//添加新闻
add(){
request({
url:'/api/add/news',
method:'post',
data:{
title:this.title,
content:this.content
}
}).then(res=>{console.log(res);})
},
//获取新闻
getnewsList(){
request({
url:"/api/get/news",
method:'get',
params:{
pageindex:this.pageindex,
pagesize:10//一个页面中显示总的新闻条数
}
}).then(res=>{
console.log(res);
this.list=res.data.list
})
},
//删除新闻
remove(id){
request({
url:"/api/delete/news",
method:'post',
data:id
}).then(res=>{
console.log(res);
})
},
prevPage(){
this.pageindex++
this.getnewsList()
},
nextPage(){
this.pageindex--
this.getnewsList()
}
}
};
</script>