效果:
1.Fly官网地址:https://wendux.github.io/dist/#/doc/flyio/readme
2.项目文件:
2.1 网络请求的request.js
//目前没有针对uni的Fly版本,使用wx版本没有问题,引入Fly import Fly from 'flyio/dist/npm/wx' //创建Fly实例 const request = new Fly() //将箭头函数实例赋值给errorPrompt //箭头函数相当于 //function (err) { // uni.showToast({ // title: err.message || 'fetch data error.', // icon: 'none' // }) //} const errorPrompt = (err) => { uni.showToast({ title: err.message || 'fetch data error.', icon: 'none' }) } //添加Fly的请求拦截器,可以通过它在请求之前做一些预处理 //请求拦截器中的request对象结构如下: //{ // baseURL, //请求的基地址 // body, //请求的参数 // headers, //自定义的请求头 // method, // 请求方法 // timeout, //本次请求的超时时间 // url, // 本次请求的地址 // withCredentials //跨域请求是否发送第三方cookie //} request.interceptors.request.use((request) => { uni.showLoading({ title: '加载中' }); return request }) //添加响应拦截器,响应拦截器会在then/catch处理之前执行 //promise 承诺,承诺需要完成的两件事,指定承诺需要完成的事,设置承诺是否实现的标准 //resolve和reject是判断承诺是否实现的两个函数 //如果请求成功,且response.data调用里有数据,说明承诺已经实现了,调用resolve方法 //如果进入了处理错误的方法,说明请求被拒绝了,调用reject方法 //响应拦截器中的response对象结构如下 //{ // data, //服务器返回的数据 // engine, //请求使用的http engine(见下面文档),浏览器中为本次请求的XMLHttpRequest对象 // headers, //响应头信息 // request //本次响应对应的请求信息 //} request.interceptors.response.use((response, promise) => { uni.hideLoading(); return promise.resolve(response.data) }, (err, promise) => { //错误走到这里,隐藏加载中,toast错误信息,处理错误 uni.hideLoading(); errorPrompt(err) return promise.reject(err) }) //export用于对外输出本模块(一个文件可以理解为一个模块)变量的接口,其他JS文件就可以通过import命令加载这个模块(文件) export default request
2.2处理网路请求的store.js
//引入request.js文件 import request from 'common/request' //const定义的变量不可以修改,而且必须初始化。 //async,异步方法用来处理请求网络数据,因为请求网络数据可能耗时,如果同步,则会影响体验和性能 const getProducts = async function (page=1) { //let是块级作用域,函数内部使用let定义后,对函数外部无影响。 //var定义的变量可以修改,如果不初始化会输出undefined,不会报错,且变量的作用域是全局的 let url = `https://api.beidian.com/mroute.html?method=beidian.h5.shop.product.list&page=${page}&shop_id=682731`; console.log(url); //使用await是执行顺序控制,每执行一个await,程序都会暂停等待await返回值,然后进行下一步 //只能在async方法里,使用await //调用Fly实例的get方法,发起网络请求 const data = await request.get(url); if (data.has_more) { return data.shop_products; } else { return false; } } const search = async function(keywords, page=1) { keywords = encodeURI(keywords); let url = `https://api.beidian.com/mroute.html?method=beidian.search.item.list&keyword=${keywords}&sort=hot&page_size=20&page=${page}`; console.log(url); const data = await request.get(url); if (data.has_more) { return data.items; } else { console.log("没有数据了!") return false; } } //每个模块内部,module变量代表当前模块,这个变量是一个对象,它的exports属性(module.exports={})是对外的接口。加载某个模块,其实是加载该模块的module.exports属性。 //exports var exports = module.exports; exports是引用 module.exports的值,而模块导出的时候,真正导出的执行是module.exports,而不是exports module.exports= { getProducts, search, }
2.3视图页面index.vue
<template> //flex:1 让所有弹性盒模型对象的子元素都有相同的长度,且忽略它们内部的内容: <view style="flex-direction: column; flex: 1;"> <block v-for="(item,index) in productList" :key="index"> <view class=""> <view style="flex-direction: column; flex: 1;"> <view style="height: 750upx;"> <image :src="item.img" mode="" style="width: 100%; height: 100%;"></image> </view> <view style="padding-top: 30upx; padding-left: 20upx; padding-right: 20upx; font-size: 30upx; font-weight: bold;"> {{item.title}}</view> <view style="padding: 20upx;"> <view> <view> ¥{{item.price}} </view> <view style="padding-left: 20upx;"> {{item.seller_count}} </view> </view> <view class="" style="flex: 1; justify-content: flex-end;"> <view> <button type="danger" size="mini">购买</button> </view> </view> </view> </view> </view> <view class="" style="background-color: #8F8F94; height: 20upx;"></view> </block> </view> </template> <script> import service from 'service/store.js'; export default { data: { productList:[ ] }, async onLoad() { const productList = await service.getProducts(1); this.productList=productList; console.log(JSON.stringify(productList)); } } </script> <style> view { display: flex; flex-direction: row; font-size: 28upx; } </style>
2.4在pages.json中加入底部导航栏实现
"tabBar": { "color": "#cdcdcd", "selectedColor": "#1296db", "borderStyle": "black", "backgroundColor": "#ffffff", "list": [{ "pagePath": "pages/home/index", "iconPath": "static/tabbar/home.png", "selectedIconPath": "static/tabbar/homeHL.png", "text": "首页" }, { "pagePath": "pages/lab/index", "iconPath": "static/tabbar/lab.png", "selectedIconPath": "static/tabbar/labHL.png", "text": "实验" }, { "pagePath": "pages/my/index", "iconPath": "static/tabbar/my.png", "selectedIconPath": "static/tabbar/myHL.png", "text": "关于" }] },
2.5加入底部导航栏的页面也要在pages.json中的pages里添加
"pages": [ //pages数组中第一项表示应用启动页 { "path": "pages/home/index", "style": { "navigationBarTitleText": "首页" } }, { "path": "pages/my/index", "style": { "navigationBarTitleText": "关于" } }, { "path": "pages/lab/index", "style": { "navigationBarTitleText": "实验" } } ],