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);
			})
		})
	}
}
相关推荐
snow@li5 分钟前
前端:前端/浏览器 可以录屏吗 / 实践 / 录制 Microsoft Edge 标签页、应用窗口、整个屏幕
前端·浏览器录屏·前端录屏·web录屏
李贺梖梖11 分钟前
CSS学习
前端·css
蚂小蚁20 分钟前
一文吃透:宏任务、微任务、事件循环、浏览器渲染、Vue 批处理与 Node 差异(含性能优化)
前端·面试·架构
狼性书生33 分钟前
uniapp实现的Tab 选项卡组件模板
前端·uni-app·vue·组件·插件
吃饺子不吃馅37 分钟前
前端画布类型编辑器项目,历史记录技术方案调研
前端·架构·github
许___38 分钟前
el-table多选模式下跨分页保留当前页选项
javascript·vue.js
拜晨1 小时前
使用motion实现小宇宙贴纸墙效果
前端·交互设计
拜晨1 小时前
使用motion实现小宇宙节目广场的效果
前端·交互设计
Q_Q19632884751 小时前
python+django/flask基于机器学习的就业岗位推荐系统
spring boot·python·django·flask·node.js·php