## 前言 * 前端开发中最重要的便是api调用,从服务端拉取数据进行业务操作,完毕之后提交数据至服务端 * 这个流程几乎涵盖了整个系统 * 下面我们来学习下标准的api调用应该如何编写 * 同时看下如何和我们的自定义组件结合起来 ## 定义一个api 1. 我们到api文件夹下创建demo.js,内容如下 ![](https://img.kancloud.cn/40/ef/40efae19007baa784f5632281207162b_1680x524.png) 2. 工程封装了`axios`方法,将常用的方法都封装好,方便大家直接调用 ## 调用api 1. 我们准备让这个方法在页面初次加载的时候调用,并把获取到的数据打印出来 2. 进入我们编写的Demo页面,编写一个测试方法 ![](https://img.kancloud.cn/b7/d2/b7d2e14ff4468a2867bcb73c8ecfba6c_926x1262.png) * `import xx from xxx` 将我们刚刚编写的api方法引入 * `created` 属于vue生命周期中`创建执行` * `getDetail` 在页面加载的时候执行,并且将返回的值打印在控制台 3. 打开系统刷新页面,发现控制台打印与mock设定一致 ![](https://img.kancloud.cn/b5/0b/b50b18702559f3fe08ed6b38358ea9f2_1544x1390.png) ## 使用同步调用api 很多业务场景,经常会有同时几个接口调用共同依赖的场景,若超过3个的话,都写在.then方法里进行操作,代码会变得非常不优雅,耦合度也高。下面我们来尝试下使用同步操作代码 1. demo增加mock接口test ![](https://img.kancloud.cn/6e/24/6e247e9abc2b1b6987752282589494c5_1426x798.png) 2. 对应api增加接口定义 ![](https://img.kancloud.cn/d6/0b/d60b62b77453dfd783d0fb739b759a99_776x610.png) 3. 更改代码,单独抽离出一个方法init,用于同步代码的操作。同时将init的返回类型打印出来 ![](https://img.kancloud.cn/95/f7/95f760de5972936dc4dc7b6239350b87_1136x1678.png) 4. 打开系统查看控制台打印,可以看到两条信息都打印成功,而且是按顺序加载。这样解耦了多个接口下都操作,代码看起来更清爽,可读性更高。 ![](https://img.kancloud.cn/7d/96/7d9678e6162a16920180272d3677261e_1720x1604.png) 5. 可以看到,返回都是一个Promise对象,具体介绍,请看:https://www.imooc.com/article/20580 6. 还有一点需要注意的是,如果需要用到promise,那么方法前必须带有`async`关键字,否则将失效 <br> <br> <br> ## 放上相关代码 * 希望大家都能把代码都手动敲出来,而不是直接复制粘贴 * `/mock/demo.js` : ~~~ import Mock from 'mockjs' function getFakeDetail() { const json = {code: 200, success: true, msg: '操作成功'}; json.data = "测试mock返回"; return json; } function getFakeTestDetail() { const json = {code: 200, success: true, msg: '操作成功'}; json.data = "测试mock test返回"; return json; } export default ({mock}) => { if (!mock) return; Mock.mock(/\/api\/demo\/detail/, 'get', getFakeDetail); Mock.mock(/\/api\/demo\/test-detail/, 'get', getFakeTestDetail); } ~~~ * `/mock/index.js` : ~~~ import user from './user'; import menu from './menu'; import demo from './demo'; /** * 模拟数据mock * * mock是否开启模拟数据拦截 */ user({mock: true}); menu({mock: true}); demo({mock: true}); ~~~ * `/api/demo/demo.js` : ~~~ import request from '@/router/axios'; export const getDetail = () => { return request({ url: '/api/demo/detail', method: 'get', }) } export const getTestDetail = () => { return request({ url: '/api/demo/test-detail', method: 'get', }) } ~~~ * `/views/demo/demo.vue` : ~~~ <template> <div> <h1>hello saber! im bladex!</h1> <x-button></x-button> </div> </template> <script> import {getDetail, getTestDetail} from '@/api/demo/demo'; export default { name: "demo", data() { return { options: [], value: '' } }, created() { const promise = this.init(); console.log(promise); }, methods: { async init() { const res = await getDetail(); if (res.data.success) { console.log(res.data.data); } else { console.log(res.data.msg); } const resTest = await getTestDetail(); if (resTest.data.success) { console.log(resTest.data.data); } else { console.log(resTest.data.msg); } }, onChange() { console.log(this.value) }, } } </script> <style scoped> </style> ~~~