Vue3仿卖座电影开发纪实(二):网络请求

951 阅读3分钟

@抓取卖座电影数据

  • 使用浏览器控制台的网络选项卡
  • 使用Fetch/XHR过滤器查看卖座电影的Ajax请求
  • 使用排序功能按响应数据量大小排序
  • 通常数据量最大的ajax请求即为当前页面的主体数据
  • 复制保存每个页面的JSON数据备用

@使用json-server搭建mock数据服务器

全局安装json-server

npm i -g json-server

导入并暴露数据

mock/mockData.js

const playings1 = require("./data/playings1.json");
const playings2 = require("./data/playings2.json");
const comings = require("./data/comings.json");
const cities = require("./data/cities.json");
const cinemas = require("./data/cinemas.json");

module.exports = () => {
  return {
      playings1,
      playings2,
      comings,
      cities,
      cinemas
  };
};

配置路由表

mock/mockRouter.json

{
    "/api/movie/playings1": "/playings1",
    "/api/movie/playings2": "/playings2",
    "/api/movie/comings": "/comings",
    "/api/movie/cities": "/cities",
    "/api/movie/cinema": "/cinemas"
}

启动mock服务器

cd mock
json-server ./mockData.js -r ./mockRouter.json -p 9000 --watch

配置快速启动脚本

package.json

  "scripts": {
     ...
    "mock":"json-server ./mock/mockData.js -r ./mock/mockRouter.json -p 9000 --watch"
  },
cd mymovie
npm run mock

@封装网络请求

axios的一般使用

参考教程

实例层封装

  • 实例中配置了请求的根路径 + 超时时间
  • 在请求拦截器中统一为所有请求注入token
  • 在响应拦截器中统一为所有响应提取核心数据 api/instance.js
import axios from "axios"

const instance = axios.create({
  baseURL: "http://localhost:9000/api",
  timeout: 3000,
});

/* 在axios实例的身上配置拦截器 */
// 添加请求拦截器
instance.interceptors.request.use(
  function (config) {
    // 在发送请求之前做些什么:为所有请求配置请求头authorization 令其携带身份认证token
    config.headers["authorization"] = "Bearer mytoken";
    return config;
  },
  function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  }
);

// 添加响应拦截器
instance.interceptors.response.use(
  function (response) {
    // 对响应数据做点什么:从响应中剥离出【服务器端返回的数据】 过滤掉axios自行封装的信息
    return response.data;
  },
  function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  }
);

export default instance;

通信层

  • 封装出通用的GET请求和POST请求
  • 封装了axios.get和axios.post方法
  • 在doPost中发起通用的POST请求
  • 在doGet中将用户数据拼接为查询参数?a=123&b=456,并发起通用的GET请求
import instance from "./instance";

/* 通用的增POST 删DELETE 改PUT 查GET  */

/* 通用的POST请求 */
export function doPost(url,data,config){
    return instance.post(url,data,config)
}

/* 通用的GET请求 */
// /movie/playings?page=3&pagesize=10
// doGet("/movie/playings",{page:3,pagesize:10})
export function doGet(url,dataObj,config){
    /* {page:3,pagesize:10} => ?page=3&pagesize=10 */
    let searchParamStr = "?"
    for(let key in dataObj){
        searchParamStr += `${key}=${dataObj[key]}`
    }
    url += searchParamStr
    console.log("url=",url);

    return instance.get(url,config)
}

应用层封装

  • 调用通信层封装好的goGet请求
  • 分别抛出简单好用的业务方法给视图层(Vue组件)使用
import { doPost, doGet } from "./crud";

/* 获取正在上映列表 */
export function getPlayings(page){
    return doGet("/movie/playings1",{page:page}).then(
        // 帮视图层直接提取出热映列表
        res => res.data.films
    )
}

/* 获取即将上映列表 */
export function getComings(){
    return doGet("/movie/comings")
}

/* 获取即将城市列表 */
export function getCities(){
    return doGet("/movie/cities")
}

/* 获取即将影院列表 */
export function getCinemas(){
    return doGet("/movie/cinemas")
}

视图层获取热映列表

  • 组件一挂载即调用应用层封装好的数据获取接口
  • 一步到位地获取指定页的热映电影
  /* 组件挂载时立即获取数据 */
  mounted() {
    getPlayings(5)
      .then((data) => (this.playings = data))
      .catch((err) => (this.err = err));
  },