axios 的二次封装

我们搜索什么,下面就展示什么,一旦搜索一个东西以后,他的数据是不是要展示,展示的话,我们请求的数据进行展示,除了搜索,包括我们的首页,也是请求数据进行展示,购物车,分类,都是请求的数据进行展示,我们打开任何一个App,或者网页,基本上他们在加载数据之前会做什么事情,先提示一个加载中的loading,有数据了,加载图标就消失掉了,吗没有请求之前,我们给你加一个loading,等你请求结束以后,我们在把loading关闭了,可以吗?我们现在针对首页来加载一个loading,
第一步:在 views/Home.vue 中引入加载
复制代码
import {Indicator} from 'mint-ui';

Indicator.open('加载中...');
第二步:在你发送请求之前执行 loading
复制代码
async getData() {
    let res = await http.$axios({
        url: '/api/index_list/0/data/1'
    });
    this.items = Object.freeze(res.topBar);
    this.newData = Object.freeze(res.data);

    // 当 DOM 都加载完毕再去执行
    this.$nextTick(() => {
        this.oBetterScroll = new BetterScroll(this.$refs.wrapper, {
            movable: true,
            zoom: true
        })
    })
},
async addData(index) {
    let res = await http.$axios({
        url: '/api/index_list/' + index + '/data/1'
    });
    if (res.constructor != Array) {
        this.newData = res.data;
    } else {
        this.newData = res;
    }

    // 当 DOM 都加载完毕再去执行
    this.$nextTick(() => {
        this.tBetterScroll = new BetterScroll(this.$refs.wrapper, {
            movable: true,
            zoom: true
        })
    })
},
第三步:有了数据时,再将加载关闭,调用close() 方法,将其关闭
复制代码
Indicator.close();
加载页面,很多页面都会用到加载,我们可以在axiox发送请求中,添加Indicator,就不需要在每个页面中加载 Indicator ,所以我们要对 axios 进行二次封装,在公司里做项目,Axios一定会进行二次封装,后期要验证用户是否为登录状态,或者是否登录,我们要验证他登录的账号对不对?你需要将当前用户信息传给后端,这时,你每次传一个特别长的字符串,很不好,我们只要写一个true,就不用验证,false才验证,这样会方便很多。我们将
复制代码
Indicator.open('加载中...');
Indicator.close();
他们封装在axios里面,就不用去每个页面去添加他们。接下来我们针对axios进行二次封装。在src下新建一个common目录,在该目录下新建一个api目录,在api目录下新建一个request.js文件。
复制代码
import axios from 'axios'
import {
	Indicator
} from 'mint-ui'

export default {
	common: {
		// 默认请求的方式
		method: 'GET',
		// 默认请求的数据
		data: {},
		// 默认请求的参数
		params: {}
	},
	$axios(options = {}) {

		// (传入的值)接收到的值 options.method  默认值 this.common.method
		options.method = options.method || this.common.method;
		options.data = options.data || this.common.data;
		options.params = options.params || this.common.params;

		// 请求前=>显示加载中
		// Indicator.open();
		Indicator.open('加载中...');

		return axios(options).then(v => {
			// console.log(v); 可以拿到数据
			let data = v.data.data;
			return new Promise((res, rej) => {
				if (!v) return rej();
				//结束 ==> 关闭加载中
				// 有数据时,再调用 close 方法将其关闭
				setTimeout(() => {
					Indicator.close();
				}, 500)
				res(data);
			})
		})
	}
}
axios 的二次封装 实现代码如下
复制代码
1, common/api/request.js
import axios from 'axios'
import {
	Indicator
} from 'mint-ui'

export default {
	common: {
		// 请求的方式
		method: 'GET',
		data: {},
		params: {}
	},
	$axios(options = {}) {
		// return 111;

		// 接收到的值 options.method  默认值 this.common.method
		options.method = options.method || this.common.method;
		options.data = options.data || this.common.data;
		options.params = options.params || this.common.params;

		// 请求前=>显示加载中
		// Indicator.open();
		Indicator.open('加载中...');

		return axios(options).then(v => {
			// console.log(v); 可以拿到数据
			let data = v.data.data;
			return new Promise((res, rej) => {
				if (!v) return rej();
				//结束 ==> 关闭加载中
				// 有数据时,再调用 close 方法将其关闭
				setTimeout(() => {
					Indicator.close();
				}, 500)
				res(data);
			})
		})
	}
}







2, views/Home.vue
<template>
	<div class="home">
		<div class="headers">
			<div class="header-main">
				<Header></Header>
				<ly-tab v-model="selectedId" :items="items" :options="options" @change="changeTab"></ly-tab>
			</div>
		</div>
		<section ref="wrapper">
			<div>
				<div v-for="(item,index) in newData" :key="index">
					<!-- {{item.data item.type}} -->
					<Swiper v-if="item.type == 'swiperList'" :swiperList="item.data"></Swiper>
					<Icons v-if="item.type == 'iconsList'" :iconsList="item.data"></Icons>
					<Recommend v-if="item.type == 'recommendList'" :recommendList="item.data"></Recommend>
					<Ad v-if="item.type == 'adList'" :adList="item.data"></Ad>
					<Like v-if="item.type == 'likeList'" :likeList="item.data"></Like>
					<Footer v-if="false"></Footer>
				</div>
			</div>
		</section>
		<Tabbar></Tabbar>
	</div>
</template>

<script>
	import Header from '@/components/home/Header.vue'
	import Swiper from '@/components/home/Swiper.vue'
	import Icons from '@/components/home/Icons.vue'
	import Recommend from '@/components/home/Recommend.vue'
	import Like from '@/components/home/Like.vue'
	import Ad from '@/components/home/Ad.vue'
	import Footer from '@/components/home/Footer.vue'
	import Tabbar from '@/components/common/Tabbar.vue'

	// 引入插件
	import BetterScroll from 'better-scroll'
	import http from '@/common/api/request.js'

	export default {
		name: "Home",
		data() {
			return {
				selectedId: 0,
				// topBar: [],
				items: [],
				newData: [],
				oBetterScroll: '',
				tBetterScroll: '',
				options: {
					activeColor: '#b0352f'
				}
			}
		},
		components: { // 挂载
			Header,
			Swiper,
			Icons,
			Recommend,
			Like,
			Ad,
			Footer,
			Tabbar
		},
		created() {
			this.getData();
		},
		mounted() { // 有数据,有节点
			// console.log(this.$refs.wrapper);
			// console.log(this.$data, this.$el);
		},
		methods: {
			async getData() {

				// 传出去
				// let aa == await http.$axios({
				// 	url: '/api/index_list/0/data/1',
				// 	data: {},
				// 	params: {},
				// 	method: 'post'
				// });
				// console.log(aa);

				// console.log(http.$axios()); // 111

				// console.log(http.run()); // 111

				// 当需要显示加载提示框时,调用 open 方法
				// Indicator.open('加载中...');

				let res = await http.$axios({
					url: '/api/index_list/0/data/1'
				});
				this.items = Object.freeze(res.topBar);
				this.newData = Object.freeze(res.data);


				// this.items = res.data.data.topBar;
				// this.newData = res.data.data.data;
				// this.items = Object.freeze(res.data.data.topBar);
				// this.newData = Object.freeze(res.data.data.data);
				// console.log(Object.freeze(res.data.data.data)); // 数组
				// console.log(Object.freeze(res.data.data.topBar));

				// 有数据时,再调用 close 方法将其关闭
				// Indicator.close();

				// 当 DOM 都加载完毕再去执行
				this.$nextTick(() => {
					this.oBetterScroll = new BetterScroll(this.$refs.wrapper, {
						movable: true,
						zoom: true
					})
				})
			},
			async addData(index) {
				let res = await http.$axios({
					url: '/api/index_list/' + index + '/data/1'
				});
				if (res.constructor != Array) {
					this.newData = res.data;
				} else {
					this.newData = res;
				}

				// 当 DOM 都加载完毕再去执行
				this.$nextTick(() => {
					this.tBetterScroll = new BetterScroll(this.$refs.wrapper, {
						movable: true,
						zoom: true
					})
				})
			},
			changeTab(item, index) {
				this.addData(index)
				// console.log(index);
			}
		}
	}
</script>

<style scoped>
	.home {
		display: flex;
		flex-direction: column;
		width: 100vw;
		height: 100vh;
		overflow: hidden;
	}

	.headers {
		width: 100%;
		height: 108px;
	}

	.headers-main {
		position: fixed;
		top: 0;
		left: 0;
		margin-top: 120px;
	}

	section {
		flex: 1;
		/* margin-top: 120px; */
		overflow: hidden;
	}

	.ly-tab {
		/* 固定定位 */
		/* position: fixed;
		top: 60px;
		left: 0; */
	}

	::v-deep .ly-tabbar {
		box-shadow: none;
		border-bottom: none;
	}
</style>
今天用MintUI组件库写了一个放大展示图片的效果出了这样几个报错:

原因:

重复引入 Vue
需要在Vue.config.js文件上配置:
复制代码
const path = require('path')
function resolve(dir) {
  return path.join(__dirname, dir)
}
 
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  // 反向代理
  devServer: {
    port: 8888,
    proxy: {
      '/chl': {
        target: 'https://v2.api-m.com',
        changeOrigin: true,
        // pathRewrite 路径重写
        pathRewrite: {
          '/chl': ''
        }
      }
    }
  },
  //解决报错 点击展示图片报错
  chainWebpack: (config) => {
    config.resolve.alias.set('@', resolve('src')).set('vue', resolve('./node_modules/vue'))
  }
})
```

vite.config.js(老师的)

```
// const {
// 	defineConfig
// } = require('@vue/cli-service')


// module.exports = defineConfig({
// 	transpileDependencies: true
// })

let path = require("path");
module.exports = {
	// 代理
	devServer: {
		proxy: {
			'/api': {
				target: "http://localhost:3000",
				changeOrigin: true,
				pathRewrite: {
					'^/api': '/api'
				}
			}
		},
	},
	configureWebpack: (config) => {
		config.resolve = {
			extensions: ['.js', '.json', '.vue'],
			alias: {
				'@': path.resolve(__dirname, './src'),
			}
		}
	},
	//解决报错 点击展示图片报错
	chainWebpack: (config) => {
		config.resolve.alias.set('@', resolve('src')).set('vue', resolve('./node_modules/vue'))
	}
}
```

vite.config.js

```
const path = require('path')
function resolve(dir) {
  return path.join(__dirname, dir)
}
 
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
	transpileDependencies: true,
	// 代理
	devServer: {
		proxy: {
			'/api': {
				target: "http://localhost:3000",
				changeOrigin: true,
				pathRewrite: {
					'^/api': '/api'
				}
			}
		},
	},
	//解决报错 点击展示图片报错
	chainWebpack: (config) => {
		config.resolve.alias.set('@', resolve('src')).set('vue', resolve('./node_modules/vue'))
	}
})
axios的二次封装 在如下两个文件中修改代码如下
复制代码
1, views/Home.vue
import http from '@/common/api/request.js'
methods: {
    async getData() {

        let res = await http.$axios({
            url: '/api/index_list/0/data/1'
        });
        this.items = Object.freeze(res.topBar);
        this.newData = Object.freeze(res.data);

        // 当 DOM 都加载完毕再去执行
        this.$nextTick(() => {
            this.oBetterScroll = new BetterScroll(this.$refs.wrapper, {
                movable: true,
                zoom: true
            })
        })
    },
    async addData(index) {
        let res = await http.$axios({
            url: '/api/index_list/' + index + '/data/1'
        });
        if (res.constructor != Array) {
            this.newData = res.data;
        } else {
            this.newData = res;
        }

        // 当 DOM 都加载完毕再去执行
        this.$nextTick(() => {
            this.tBetterScroll = new BetterScroll(this.$refs.wrapper, {
                movable: true,
                zoom: true
            })
        })
    },
    changeTab(item, index) {
        this.addData(index)
    }
}


2, components/common/api/request.js
import axios from 'axios'
import {
	Indicator
} from 'mint-ui'

export default {
	common: {
		// 请求的方式
		method: 'GET',
		data: {},
		params: {}
	},
	$axios(options = {}) {
		// return 111;

		// 接收到的值 options.method  默认值 this.common.method
		options.method = options.method || this.common.method;
		options.data = options.data || this.common.data;
		options.params = options.params || this.common.params;

		// 请求前=>显示加载中
		// Indicator.open();
		Indicator.open('加载中...');

		return axios(options).then(v => {
			// console.log(v); 可以拿到数据
			let data = v.data.data;
			return new Promise((res, rej) => {
				if (!v) return rej();
				//结束 ==> 关闭加载中
				// 有数据时,再调用 close 方法将其关闭
				setTimeout(() => {
					Indicator.close();
				}, 500)
				res(data);
			})
		})
	}
}
相关推荐
阿珊和她的猫3 小时前
深入理解与手写发布订阅模式
开发语言·前端·javascript·vue.js·ecmascript·状态模式
Q_Q5110082853 小时前
python基于web的汽车班车车票管理系统/火车票预订系统/高铁预定系统 可在线选座
spring boot·python·django·flask·node.js·汽车·php
yinuo3 小时前
一行 CSS 就能搞定!用 writing-mode 轻松实现文字竖排
前端
snow@li3 小时前
html5:拖放 / demo / 拖放事件(Drag Events)/ DataTransfer 对象方法
前端·html·拖放
爱看书的小沐3 小时前
【小沐杂货铺】基于Three.js渲染三维风力发电机(WebGL、vue、react、WindTurbine)
javascript·vue.js·webgl·three.js·opengl·风力发电机·windturbine
浪裡遊5 小时前
Nivo图表库全面指南:配置与用法详解
前端·javascript·react.js·node.js·php
罚时大师月色6 小时前
Vue+ts 如何实现父组件和子组件通信
javascript·vue.js·ecmascript
漂流瓶jz6 小时前
快速定位源码问题:SourceMap的生成/使用/文件格式与历史
前端·javascript·前端工程化
samroom6 小时前
iframe实战:跨域通信与安全隔离
前端·安全