学习不一样的vue4:mock与axios实战1
学习不一样的vue4:mock与axios实战1
首先
任务一
- 利用 mockjs模拟2个接口,一个菜单列表数据,一个新增菜单
 - 前台实现请求菜单数据和新增菜单的功能
 
Mockjs
为什么要用Mockjs?
- 开发时,后端还没有写好接口,前端只能写静态模拟数据。
 - 将模拟数据写在js文件里面,数据太多了,看的眼花缭乱。
 - 后端完成后接口后,我们前端又要挨个去改api的url。
 - 写模拟数据太麻烦.需要收集很多的资源,图片,地址,随机数等;
 
Mockjs可以做什么?
axios
vue.js 自2.0版本已经不对 vue-resource 更新了,官方推荐使用 axios 解决方案,而且axios 使用了Promise,所以axios是一个不错的选择。
如果你还不了解axios的用法,请阅读axios中文文档
安装
- 安装 mock axios
 
| 
 1 
 | 
 npm install mockjs axios 
 | 
- 安装 axios-mock-adapter
axios-mock-adapter 是axios与mock配置器,简单来说就是把二者结合在一起的工具,axios-mock-adapter文档
 
| 
 1 
 | 
 npm install axios-mock-adapter --save-dev 
 | 
创建 mock
新建src/mock/data/todoList.js
这里todoList.js文件是初始化我们需要的数据,在进行导出,复制下面以下代码到src/mock/data/todoList.js。
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
 | 
 import Mock from 'mockjs'; // 导入mockjs 模块 
let Todos = []; // 定义我们需要的数据 
const COUNT = [1, 2, 3, 4, 5]; // 定义我们需要数量 
for (let i = 1; i <= COUNT.length; i++) { 
Todos.push(Mock.mock({ // 根据数据模板生成模拟数据。 
id: Mock.Random.guid(), // 随机id 
title: Mock.Random.first(), // 随机标题 
isDelete: false, //是否删除 
locked: Mock.Random.boolean(), // 随机锁定 
record: COUNT.map(() => { // 代办单项列表的数据 
return { 
text: Mock.Random.cparagraph(2), // 随机内容 
isDelete: false, //是否删除 
checked: Mock.Random.boolean() //是否完成 
}; 
}) 
})); 
} 
export { // 导出列表数据 
Todos 
}; 
 | 
新建src/mock/mock.js
这里的 mock.js 从我的命名就可以看出它是核心,它的作用就是模拟ajax请求的接口, 生成并返回模拟数据.复制下面代码到src/mock/mock.js。
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
 | 
 import axios from 'axios'; 
import MockAdapter from 'axios-mock-adapter'; 
import Mock from 'mockjs'; 
import { 
Todos 
} from './data/todoList'; // 导入Todos数据 
export default { 
/** 
* mock start 
*/ 
start() { // 初始化函数 
let mock = new MockAdapter(axios); // 创建 MockAdapter 实例 
// 获取todo列表 
mock.onGet('/todo/list').reply(config => { // config 指 前台传过来的值 
let mockTodo = Todos.map(tode => { // 重组 Todos数组,变成我们想要的数据 
return { 
id: tode.id,  
title: tode.title, 
count: tode.record.filter((data) => { 
if (data.checked === false) return true; 
return false; 
}).length, // 过滤到record里面 ‘checked’ 为true的数据,因为它们已经被完成了 
locked: tode.locked, 
isDelete: tode.isDelete 
}; 
}).filter(tode => { 
if (tode.isDelete === true) return false; // 过滤掉 ‘isDelete’为true,因为已经被删除了。 
return true; 
}); 
return new Promise((resolve, reject) => { 
setTimeout(() => { 
resolve([200, { 
todos: mockTodo // 返回状态为200,并且返回todos数据 
}]); 
}, 200); 
}); 
}); 
// 新增一条todo 
mock.onPost('/todo/addTodo').reply(config => { 
Todos.push({ 
id: Mock.Random.guid(), 
title: 'newList', 
isDelete: false, 
locked: false, 
record: [] 
}); 
return new Promise((resolve, reject) => { 
setTimeout(() => { 
resolve([200]); 
}, 200); 
}); 
}); 
} 
}; 
 | 
导出 mock
- 新建src/mock/index.js,并且复制以下代码,这里的index作用在于方便其他文件引入。
 
| 
 1 
2 
 | 
 import mock from './mock';  
export default mock; // 导入同级下mock.js的内容,并且导出 
 | 
引入 mock
- 打开 src/main.js,并且复制以下代码,这里的作用就是全局加载mock,执行初始化函数函数,这样的本地我们设定的接口,就可以在全局调用了。
 
| 
 1 
2 
 | 
 import Mock from './mock'; // 引入mock模块 
Mock.start(); //并且执行初始化函数 
 | 
封装api函数
- 新建 src/api/api.js
 - 我们把所有需要调用的接口,全部写到一个文件里面,封装成一个一个的函数,需要使用的时候我们直接调用这个函数即可,这里写的话,逻辑就比较清晰,接口需要改动的时候也能快速定位,维护成本就降低了。
 - 复制下面代码到 src/api/api.js
 
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
 | 
 import axios from 'axios'; //导入axios模块 
export const getTodoList = params => { //封装一个函数,名为getTodoList 
return axios.get(`/todo/list`, { // 请求路径 ‘/todo/list’ 
params: params 
}); 
}; 
export const addTodo = params => { 
return axios.post(`/todo/addTodo`, params).then(res => res.data); 
}; 
 | 
调用接口
知识点
- vue生命周期
 - created()函数,一般是实例创建完成,但是dom还没有开始渲染时候执行,如果我们想在页面渲染之前就请求数据,那么我们就把ajax放在里面。
 - 绑定class
 - 复制以下代码到 src/components/menus.vue
 
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
 | 
 <template> 
<!--绑定点击事件goList),并且判断当todoId 时候 item.id时,文字高亮度--> 
<div class="list-todos"> 
<!-- 绑定class,当items循环中的id等于我们设置的选中todoId时候,就会加上active这个calss,这样样式就会发生变化。--> 
<a @click="goList(item.id)" class="list-todo list activeListClass" :class="{'active': item.id === todoId}" v-for="item in items"> 
<span class="icon-lock" v-if="item.locked"></span> 
<span class="count-list" v-if="item.count > 0">{{item.count}}</span> 
{{item.title}} 
</a> 
<a class=" link-list-new" @click="addTodoList"> 
<span class="icon-plus"> 
</span> 
新增 
</a> 
</div> 
<template/> 
<script> 
import { getTodoList, addTodo } from '../api/api'; // 引入我们 封装好的两个接口函数。 
export default { 
data() { 
return { 
items: [], // 菜单数据 
todoId: '' // 默认选中id 
}; 
}, 
created() { // 调用请求菜单列表数据的接口 
getTodoList({}).then(res => { 
const TODOS = res.data.todos; // 数据都会返回在res.data里面。 
this.items = TODOS; // 我的把菜单数据赋值给定义的this.items 
this.todoId = TODOS[0].id; // 把菜单数据的默认的第一个对象的id赋值给默认选中的id 
}); 
}, 
methods: { 
goList(id) { // 点击菜单时候,替换选中id 
this.todoId = id; 
}, 
addTodoList() { // 点击新增按钮时候 
// 调用新增菜单的接口,在接口调用成功在请求数据 
addTodo({}).then(data => { 
getTodoList({}).then(res => { 
const TODOS = res.data.todos; 
this.todoId = TODOS[TODOS.length - 1].id; 
this.items = TODOS; 
}); 
}); 
} 
} 
}; 
</script> 
 | 
                    
                
                
            
        
浙公网安备 33010602011771号