【uniapp】使用Promise封装request

目录

1、创建config目录

2、创建settings.js

3、创建目录utils

4、创建request.js

5、创建api目录

6、创建apis.js文件

7、业务系统调用

[7.1 业务系统banner](#7.1 业务系统banner)

[7.2 业务系统荣誉页面(传参)](#7.2 业务系统荣誉页面(传参))


前言:使用Promise封装request

1、创建config目录

根目录下创建config目录

2、创建settings.js

在config目录下创建settings.js文件

const rootUrl='你的地址/smart/'
// const rootUrl='http://127.0.0.1:8000/smart/'
// 表示导出, 在任意js中可以导入 导入就是这个对象
export const api ={
  welcome:rootUrl + 'welcome/',
  banner:rootUrl + 'banner/',
  collection:rootUrl + 'collection/',  
  area:rootUrl + 'area/',
  statistics:rootUrl + 'statistics/',
  text_record:rootUrl + 'text_record/',
  userinfo:rootUrl + 'userinfo/',
  honorexperience:rootUrl + 'honorexperience/', //成绩荣誉
  character:rootUrl + 'character/',  // 汉字拼音
  zici:rootUrl +'zici/', // 查询英文
  defineword:rootUrl +'defineword/', // 有道单词翻译
  words:rootUrl +'words/'  // 查询英文
}

3、创建目录utils

在项目根目录下创建utils目录

4、创建request.js

在utils目录下创建request.js

import {api	} from '../config/settings.js';

// 通用的发送请求函数  
export function sendRequest(config) {  
  return new Promise((resolve, reject) => {  
    uni.request({  
      ...config,  
      success: (res) => {  
		  
        if (res.statusCode >= 200 && res.statusCode < 300) {  
			console.log("1111")
          resolve(res); // 假设服务器在响应体中返回了数据  
        } else {  
			console.log("222")
			uni.showToast({
				title:res.data.msg,
				icon:'none',				
			})
          reject(new Error(`HTTP Error: ${res.statusCode}`));  
        }  
      },  
      fail: (err) => {  
		  console.log("3333")
        reject(err); // 网络错误或其他请求失败的情况  
      },  
    });  
  });  
}  

// function sendRequest(config) {  
//   return new Promise((resolve, reject) => {  
//     uni.request({  
//       ...config,  
//       success: (res) => {  
//         if (res.statusCode >= 200 && res.statusCode < 300) {  
//           resolve(res.data); // 假设服务器在响应体中返回了数据  
//         } else {  
//           reject(new Error(`HTTP Error: ${res.statusCode}`));  
//         }  
//       },  
//       fail: (err) => {  
//         reject(err); // 网络错误或其他请求失败的情况  
//       },  
//     });  
//   });  
// }  

5、创建api目录

在根目录创建api目录

6、创建apis.js文件

在api目录下创建apis.js文件

import {api} from '../config/settings';
import {sendRequest} from '../utils/request.js';

// 获取横幅数据的函数  
export function apiGetBanner() {  
  return sendRequest({  
    url: api.banner,  
    method: 'GET',  
    header: {  
      'Content-Type': 'application/json', // 注意这里使用了标准的大写形式  
    },  
  });  
}  


// 获取荣誉数据
export function apiFetchHonorData(query){
    return  sendRequest({
    url: api.honorexperience,
    method: 'GET',
    data: {
      title: query
    }      
  })
};

7、业务系统调用

7.1 业务系统banner

<template>
	<view class="pageBg">


		<!-- 轮播图 -->
		<view class="banner">
			<swiper autoplay indicator-dots circular indicator-color="#FFFFFF" interval="3000">
				<swiper-item v-for="(item,index)  in banner_list" :key="index">
					<image :src="item.img" mode="aspectFill" />
				</swiper-item>
			</swiper>
		</view>
		<view class="notice">

			<uni-notice-bar showIcon scrollable single :text="title"></uni-notice-bar>

		</view>



		<!-- 快捷入口 -->
		<view class="grid-container">

			<navigator class="grid-item" url="/pages/addEnglish/addEnglish">
				<image class="grid-icon" src="/static/images/index/menu/xx.png" />
				<text class="grid-text">添加单词</text>
			</navigator>
			<navigator class="grid-item" url="/pages/addHonor/addHonor">
				<image class="grid-icon" src="/static/images/index/menu/sq.png" />
				<text class="grid-text">添加荣誉</text>
			</navigator>
			<navigator class="grid-item" url="/pages/honorWall/honorWall">
				<image class="grid-icon" src="/static/images/index/menu/rl.png" />
				<text class="grid-text">成长荣誉</text>
			</navigator>
			<navigator class="grid-item" url="/pages/wordRecognition/wordRecognition">
				<image class="grid-icon" src="/static/images/index/menu/yy.png" />
				<text class="grid-text">生字游戏</text>
			</navigator>
			<navigator class="grid-item" url="/pages/freeDictionary/freeDictionary">
				<image class="grid-icon" src="/static/images/index/menu/jf.png" />
				<text class="grid-text">新华字典</text>
			</navigator>
			<navigator class="grid-item" open-type="reLaunch" url="/pages/my/my">
				<image class="grid-icon" src="/static/images/index/menu/xl.png" />
				<text class="grid-text">个人中心</text>
			</navigator>
		</view>


		<!-- 底部 -->
		<view class="bottom">
			<navigator class="btv" open-type="reLaunch" url="/pages/reinforcement/reinforcement">
				<image class="btimg" src="/static/images/index/bottom/cute1.png" mode="scaleToFill" />
			</navigator>
			<navigator class="btv" open-type="reLaunch" url="/pages/words/words">
				<image class="btimg" src="/static/images/index/bottom/cute4.png" mode="scaleToFill" />
			</navigator>
			<navigator class="btv" url="/pages/wordTranslator/wordTranslator">
				<image class="btimg" src="/static/images/index/bottom/cute2.png" mode="scaleToFill" />
			</navigator>
			<navigator class="btv" url="/pages/read/read">
				<image class="btimg" src="/static/images/index/bottom/cute3.png" mode="scaleToFill" />
			</navigator>


		</view>

	</view>
</template>

<script setup>
// import {api} from '../../config/settings';
import {ref,onMounted} from 'vue';
import {apiGetBanner} from '@/api/apis.js';
const title = ref('Hello');
const banner_list = ref([]); // 初始化空数组

onMounted(async () => {  
  try {  
    const res = await apiGetBanner();  
    banner_list.value = res.data.banner; // 更新bannerList  
    title.value = res.data.notice.title; // 更新通知  
    // console.log(res);  
  } catch (error) {  
    console.error('Error fetching banner data:', error);  
    // 可以在这里添加额外的错误处理逻辑,比如重置状态或显示错误消息  
    // banner_list.value = []; // 例如,重置bannerList为空数组  
    // title.value = ''; // 例如,重置title为空字符串  
  }  
});
	
</script>


<style lang="scss" scoped>
	// .banner {
	// 	width: 100%;
	// 	height: auto;
	// 	margin-top: 1rpx;
	// 	margin-bottom: 1;
	// }

	.banner image {
		width: 100%;
		/* 图片宽度拉伸至容器宽度  */
		height: 100%;
		/* 图片高度拉伸至容器宽度  */
		object-fit: cover;
		/* 图片将覆盖整个容器区域,可能被裁剪 */
	}

	.notice {
		margin-top: 5rpx;

	}

	.grid-container {
		display: flex;
		flex-wrap: wrap;
		justify-content: space-around;
		margin-top: 20rpx;



	}


	.grid-item {
		display: flex;
		flex-direction: column;
		/* 如果想要垂直排列图标和文本,则设置此属性(但通常对于水平居中的情况,这个属性不是必需的) */
		justify-content: center;
		/* 垂直居中 */
		align-items: center;
		/* 水平居中(但在flex-direction为column时,这个属性控制的是子元素在交叉轴上的对齐,即在这里不起作用) */
		/* 注意:如果flex-direction是column,那么align-items将不会影响水平对齐 */
		width: 30%;
		/* 根据需要调整 */
		margin-bottom: 5px;
		padding: 20px;
		box-sizing: border-box;
		border: 1px solid #ddd;
		border-radius: 5px;
		text-align: center;
		/* 这个属性对于flex容器本身不是必需的,除非你想要容器内的非flex子元素居中 */
	}

	.grid-icon {
		width: 50px;
		/* 根据需要调整 */
		height: 50px;
		/* 根据需要调整 */
		margin-bottom: 0;
		/* 如果不需要图标和文本之间有额外的间距,可以设置为0 */
	}

	.grid-text {
		font-size: 14px;
		margin-top: 5px;
		display: flex;

		/* 如果不需要额外的顶部间距,可以设置为0,但通常这不是必需的,因为align-items: center已经处理了垂直对齐 */
	}

	.bottom {
		display: flex;
		justify-content: space-evenly;
		margin-top: 5rpx;
		flex-wrap: wrap;
	}

	.bottom .btv .btimg {
		width: 345rpx;
		height: 200rpx;
	}
</style>

7.2 业务系统荣誉页面(传参)

这里存在检索查询,注意检索查询的传参

<template>
<view class="pageBg">

  <view class="header">
    <!-- 搜索框 -->
    <input type="text" v-model="searchQuery" placeholder="搜索荣誉标题" class="search-input" />

    <!-- 确定按钮 -->
    <button @click="searchHonor" class="search-button">
      <image src="/static/images/honorWall/ss.png" class="search-icon" />
    </button>

    <!-- 新增按钮 -->
	<navigator url="/pages/addHonor/addHonor">
		<button class="add-button">
		  <image src="/static/images/honorWall/add.png" class="add-icon" />
		</button>
	</navigator>
    
  </view>

  <!-- 列表展示 -->
  <view v-if="honorList.length > 0" class="honor-list">
    <view v-for="(item,index) in honorList" :key="item.id"  class="honor-item">
		 <text>{{ index + 1 }}</text>  
      <text>{{ item.type_display }}</text>
      <text>{{ item.title }}</text>
      <text>{{ formatDate(item.date_earned) }}</text>
    </view>
  </view>  


  <!-- 无数据时的占位提示 -->
  <view v-else class="no-data">
    <text>暂无荣誉数据</text>
  </view>
	
</view>
</template>

<script setup>
import { api } from '../../config/settings';
import { ref, onMounted, watch } from 'vue';
import {apiFetchHonorData} from '@/api/apis.js';
import { useRouter } from 'vue-router';

// 定义存储荣誉数据的变量
const honorList = ref([]);

// 查询条件
const searchQuery = ref('');

// 格式化日期的方法
const formatDate = (dateStr) => {
  const date = new Date(dateStr);
  return `${date.getFullYear()}-${('0' + (date.getMonth() + 1)).slice(-2)}-${('0' + date.getDate()).slice(-2)}`;
};

  
// 默认查询
const fetchHonorData = async () => {  
  try {  
    const res = await apiFetchHonorData(); // 初始加载时不带查询条件  
    honorList.value = res.data || []; // 确保即使响应中没有 data 字段,honorList 也是一个数组  
  } catch (error) {  
    console.error('组件挂载时获取荣誉数据失败:', error);  
    // 可以选择在这里处理错误,比如显示一个错误消息  
  }  
}
//挂载时执行默认查询
onMounted(fetchHonorData);  
//  搜索查询 
const searchHonor = async () => {  
  try {  
    const res = await apiFetchHonorData(searchQuery.value);  
    honorList.value = res.data || []; // 更新荣誉列表  
  } catch (error) {  
    console.error('搜索荣誉数据时失败:', error);  
    // 可以选择在这里处理错误,比如显示一个错误消息或重置查询框  
  }  
};  

</script>

<style lang="scss" scoped>
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.search-input {
  flex-grow: 1;
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 5px;
}

.search-button {
  display: flex;
  align-items: center;
  color: white;
  border: none;
  border-radius: 5px;
  padding: 10px;
  cursor: pointer;
}

.search-icon {
  width: 24px;
  height: 24px;
}

.add-button {
  display: flex;
  align-items: center;
  color: white;
  border: none;
  border-radius: 5px;
  padding: 10px;
  cursor: pointer;
}

.add-icon {
  width: 24px;
  height: 24px;
}

.honor-list {
  padding: 10px;
}

// .honor-item {
//   display: flex;
//   justify-content: space-between;
//   border-bottom: 1px solid #ddd;
//   padding: 10px 0;
// }
.honor-item {  
  display: flex;  
  align-items: center; // 确保所有子元素垂直居中  
  border-bottom: 1px solid #ddd;  
  padding: 10px 0;  
}  
  
.honor-item > text:nth-child(1) { // 序号列  
  width: 40px; // 固定宽度  
  text-align: center;  
}  
  
.honor-item > text:nth-child(2) { // 类型显示列  
  width: 60px; // 根据内容调整或固定宽度  
  text-align: left; // 或根据需求调整  
}  
  
.honor-item > text:nth-child(3) { // 标题列  
  flex-grow: 1; // 填充剩余空间  
  min-width: 0; // 允许收缩到内容的最小宽度  
  white-space: nowrap; // 防止文本换行  
  overflow: hidden; // 隐藏溢出内容  
  text-overflow: ellipsis; // 使用省略号表示溢出文本  
  margin: 0 10px; // 可选:增加左右间距以改善可读性 

}  
  
.honor-item > text:nth-child(4) { // 日期列  
  width: 120px; // 固定宽度  
  text-align: right; // 根据需求调整  
}

.no-data {
  text-align: center;
  padding: 20px;
  color: #999;
}
</style>
相关推荐
一个处女座的程序猿O(∩_∩)O1 小时前
小型 Vue 项目,该不该用 Pinia 、Vuex呢?
前端·javascript·vue.js
hackeroink4 小时前
【2024版】最新推荐好用的XSS漏洞扫描利用工具_xss扫描工具
前端·xss
迷雾漫步者6 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-6 小时前
验证码机制
前端·后端
燃先生._.7 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
高山我梦口香糖8 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
m0_748235248 小时前
前端实现获取后端返回的文件流并下载
前端·状态模式
m0_748240259 小时前
前端如何检测用户登录状态是否过期
前端
black^sugar9 小时前
纯前端实现更新检测
开发语言·前端·javascript