.
  • 最新新闻
  • 安卓手机app开发用什么软件_app开发_大鱼科技
    搅局者来了,他叫小程序(微信、支付宝),也叫直达服务(小米)。江湖的玩法变了。 右下角的墨迹天气,是工具类App里的老炮,用户每天开一次、每次瞅一眼的打开方式,让他很头疼。「这怎么卖广告?」 为了挣钱,他在【天气】下面放了一坨新闻,还搞了个【时景】的UGC体系,提升停留时长。又在【我】的页面放了一堆广告入口。
  • 制作手机app大概费用多少钱_app开发_大鱼科技
    有时为了突出名称的意义,可能会跟品牌不一致,但网民搜索又可能搜索不到,这时关键字优化就很重要了,核心优化点在于:内容描述中必须包含核心关键字,并获得较好排名,如搜索『简历』,你的简历相关的小程序是否比较靠前。
  • 开发一个app需要多少钱费用_app开发_大鱼科技
    微信的表情雨让中国人的社交充满了人情味儿。当你在对话框输入“么么哒”或者“想你了”,聊天页面会掉下相应的表情雨,成为大多情侣互传情愫的标准动作。中国传统情人节日“七夕节”已至,情侣们在微信“秀恩爱”的方式又多了一种——黄金红包。
  • 什么是小程序_小程序开发需要多少钱_app开发_大鱼科技
    什么是小程序:小程序是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或者搜一下即可打开应用。也体现了“用完即走”的理念,用户不关心是否安装太多应用的问题。应用将无处不在,随时随地可用,但又无需安装卸载。
  • 看牌器 透视在哪里买_app开发_大鱼科技
    这个微信小程序的创意始于2012年,当时仅仅开发了Win平台桌面应用,随着移动互联网发展,开发技术栈难度降低
  • 做一个平台app需要多少钱_app开发_大鱼科技
    访问次数:昨日访问小程序内所有页面总次数,多个页面之间的跳转、同一页面的重复访问计为多次访问。 访问人数:昨日访问小程序内所有页面的总用户数,同一用户多次访问不重复计。 新访问用户数:首次访问小程序页面的用户数,同一用户多次访问不重复计。
  • 一天能赚2万的黑方法_app开发_大鱼科技
    没深思小程序最近一个月内更新7次背后是微信内部前所未有的力度在支持小程序(公众号都不曾有此殊遇),特别是微信刚公布2017年Q1月活账号破9.38亿。面对如此巨大的流量洼地,我们如何借助小程序来低成本/0成本获取用户?
  • 网赌破解器哪里下载_app开发_大鱼科技
    小程序定位 对于公司而言,小程序究竟是一个什么产品定位?以目前的大环境而言,无非就是几个关键点: 蹭一波热点,吸引眼球,做小程序这件事情本身就是一个吸引眼球的事情; 延伸产品线,对已有产品线做一个开辟,确保整个线的完整性; 借助小程序,赶上这趟车,营销导流;
  • 定制一款app大概需要多少钱_app开发_大鱼科技
    很多人不禁要对此举的意义发问:以微信的算法而出的搜索结果,岂不是严重遏制了新生小程序的后来者居上?这样即使定义了关键词,对推广而言并没有实质性的意义?微信官方自然也想到了与之相辅相成的策略,我们甚至可以认为后来的这步棋才是微信的本来目的。那就是于6月中旬首次出现于人们视野中的「搜索关键词广告」
  • 软件外包公司_app开发_大鱼科技
    代码的复杂度是评估一个项目的重要标准之一。较低的复杂度既能减少项目的维护成本,又能避免一些不可控问题的出现。然而在日常的开发中却没有一个明确的标准去衡量代码结构的复杂程度,大家只能凭着经验去评估代码结构的复杂程度,比如,代码的程度、结构分支的多寡等等。当前代码的复杂度到底是个什么水平?什么时候就需要我们去优化代码结构、降低复杂度?这些问题我们不得而知。 因此,我们需要一个明确的标准去衡量代码的复杂度。
  • 热门新闻
怎么做一个自己的软件_app开发_大鱼科技
时间:2021-01-11 17:57:23
怎么做一个自己的软件_app开发_大鱼科技

无论是app还是小程序或者其他端,交互中请求无处不在。

一个优秀的封装类,能让你的开发效率事半功倍,所以封装逻辑至关重要,当然我也是个小菜鸟,跟着自己的思路写过一些封装方法,一方面是想不足之处还望路过的大神给予指正,二者是为新手打开一个善于封装思维的大门,下面进入到前置知识。

Api: cnodejs.org/api/v1

Ts: 简易的类型声明、接口等

Es6:结构赋值、扩展运算、promise、export等

Taro:类react,以及小程序基础知识等

1.梳理Taro的请求 Taro.request,实现最简易的请求方法

import Taro from '@tarojs/taro'

//回调调用

function doRequestAction(){

Taro.request({

url: '',

data: {},

header: {},

success: res => {},

fail: err => {},

complete: info => {}

})

}

// promise调用

function doRequestAction(){

Taro.request({

url: '',

data: {},

header: {}

})

.then(res=>{})

.catch(err=>{})

.finally(()=>{})

}

复制代码

其中利弊不多做介绍,我们将会用到promise的请求方式。

2.梳理会用到的请求结构,以及定义的文件分类:

  • 接口地址,也就是我们常说的url,存放于api.ts文件中

  • 请求方法,也就是我们封装的方法,我们存放于request.ts文件中

  • 接口类型,也就是我们声明数据类型的文件,我们存放于inter.d.ts文件中

  • 配置文件,常用的全局请求域名,其他不动参数等,我们这里只是简单的示例因此不需要,如果有需要请大家自行配置

文件名

作用

api.ts

存放接口地址、以及统一请求域名前缀

request.ts

封装公共请求方法、以及调用方法集合

inter.d.ts

ts的声明文件,主要存放返回值类型,请求参数类型等

3.接入promise声明自己的方法并返回自己的promise请求对象

我这里尽量写es6写法让大家在今后的项目开发中更加顺畅的使用,当然在自己的项目中请结合实际情况使用,不要盲目的接入一些新的写法。下面进入知识点梳理:

  • 请求是否loading,真 ? 结束隐藏loading : ' '

  • loading层是否开启mask

  • loading文字参数可自定义

  • 请求失败是否弹出我们的报错信息

  • url在不以http/https的情况下使用自定义接口

import Taro from '@tarojs/taro'

// 暂时考虑 req的属性都会传入

const doRequestAction = (req) => {

return new Promise((resolve, reject) => {

if (req.loading) Taro.showLoading({ title: req.title ? req.title : '数据加载中...' })

Taro.request({

url: /^http(s?):\/\//.test(req.url) ? req.url : '', //暂时留空

method: 'POST',

data: {},

header: { 'content-type': 'application/x-www-form-urlencoded' }

})

.then(res => {})

.catch(err => {

//报错提示

})

.finally(() => {

if (req.loading) Taro.hideLoading()

})

})

}

复制代码

4.分离请求参数并使用ts声明传入值与类型

1.将使用到的参数进行分离 2.每个参数给出默认值,如果不传人将用默认值代替 3.使用ts声明参数类型

export interface RequestBase {

url: string, //字符串

method: 'POST' | 'GET', //常规请求方式,根据项目要求添加

data: any, // 每次的参数都是不固定的,因此我们暂时不声明数据类型

header: RequestHeader, // 下面的requestheader类型,

loading: boolean, // 请求是否开启loading层

mask: boolean, //开启loading层的情况下是否不能点击,全屏遮罩

title: string, //开启loading层的提示内容

failToast: boolean //如果请求是否,我是否直接弹出我的提示

}

export interface RequestHeader {

'content-type': string // 表示content-type类型必须声明

}

复制代码

上面的header,我重新定义了一个接口来声明类型,是为了更方便的去管理这个数据,试想如果我们平时需要将用户的token带入到header里面,那么我们就会在RequestHeader中在声明一个token字段。

所谓的接口也就相当于我们这个数据里面有什么字段,字段是什么类型。

所以,我们在header中在加入token字段,实际项目中,可能还会带入加密串,时间,以及其他的辅助验证字段,这里只为了大家方便开发做出示例,实际还需看项目声明。

特殊提醒:ts是可以不加逗号的

export interface RequestHeader {

'content-type': string // 表示content-type类型必须声明

token: string

}

复制代码

声明我们的默认参数,在用户没有参数传入的情况下,将会使用我们的默认参数来辅助请求。

// 使用默认参数,当数据不传入指定字段时替代

const NormalRquestData: RequestBase = {

url: api.DOMAIN, // 默认请求地址

method: 'GET', // 默认get请求

header : { // 默认使用的header头

"content-type": 'application/x-www-form-urlencoded',

token: ''

},

data: {}, // 默认没有参数,传入空对象

loading: true, //默认开启loading层

mask: true, //请求时不需要点击

title: '数据加载中', //loading提示文字

failToast: false // 一般我们会处理相应业务逻辑,就不直接提示阻断流程

}

复制代码

思考问题,我们如果每次动态 带上我们token? 用户刚开始进入小程序,这时可能是没有授权,后面授权了我们要及时更新token来达到用户交互目的 这时我们可以将header提出,当然我一般会在我的状态管理中操作,这里做个例子为大家提供思路。

  • 将token作为可选字段

  • 封装方法每次请求动态提取token

  • 方法返回类型为我们定义的RequestHeader类型

// inter.d.ts

export interface RequestHeader {

'content-type': string // 表示content-type类型必须声明

token?: string // token可能不存在,如果存在就是字符串类型

}

//request.ts 获取header头 返回值是RequestHeader类型

const getRequestHeader = (): RequestHeader => {

let token: string = Taro.getStorageSync('token')

return token ? {

"content-type": 'application/x-www-form-urlencoded',

token: token

} : {

"content-type": 'application/x-www-form-urlencoded'

}

}

复制代码

5.在参数某些字段不传入的情况下,我们使用自己的参数字段进行默认填充

思考问题:RequestBase参数都是必传,但是我们的请求的时候参数都是可传,如果我们将其都改为可选参数,这个时候如果我们使用req.title(loading标题)、req.url('请求api地址') 在ts的检测下,这些参数都是可能不存在的,这样我们会写大量判断,那么我们的代码就会变得相当糟糕~!因此我们再声明一个接口用来可选参数的规范。

// 遍历RequestBase中所有key,都改为可选参,这样我们就只管维护RequestBase

type Request = {

[K in keyof RequestBase]?: RequestBase[K]

}

复制代码

改造请求方法,并声明各个类型,使ts更加规范, 将接口类使用inter导入,也将之前的api改成Api统一首字母大写

import Taro from '@tarojs/taro'

import * as Api from './api'

import * as Inter from './inter.d'

// 请求传入reqData参数 返回promise对象 因为全局请求我每次返回的类型都是不一样的,所以我直接any

const doRequestAction = (reqData: Inter.Request): Promise<any> => {

// 将不存在的参数字段使用默认值进行替换

let req: Inter.RequestBase = { ...NormalRquestData, ...reqData }

return new Promise((resolve, reject) => {

//检测是否开启loading层 是否打开msak

if (req.loading) Taro.showLoading({ title: req.title, mask: req.mask })

Taro.request({

url: req.url, //引入我的接口是特殊声明的,所以我就不检测http/https了

method: req.method,

data: req.data,

header: req.header

})

.then(res => {

// 大多数请求中 success并不代表成功,需要我们自己检测statusCode来确保

if (res.statusCode === 200) {

resolve(res.data) // 成功

} else {

// 如果失败 检测是否直接提示信息

if(req.failToast) Taro.showToast({ title: '网络不好,请求失败!' })

reject(res) // 失败

}

})

.catch(err => {

// 如果失败 检测是否直接提示信息

if (req.failToast) Taro.showToast({ title: '网络不好,请求失败!' })

reject(err)

})

.finally(() => {

// 请求结束 关闭loading层

if (req.loading) Taro.hideLoading()

})

})

}

复制代码

ok,请求方法写到这里我们暂时只能告一段落了

6.完善api.ts,声明全局域名以及每个接口的定义.

//定义全局请求地址,因为我们用到的地址是https://cnodejs.org/api/v1

export const DOMAIN: string = 'https://cnodejs.org/'

// 声明获取主题首页接口地址并导出

export const topics: string = DOMAIN + 'api/v1/topics'

复制代码

7.观察api,声明请求data文件,以及使用请求并返回promise以及返回类型 返回类型: cnodejs.org/api/v1/topi… 自己观察我就不截图了。

// 请求主题接口参数类型

export interface TOPICSDATA {

page: number,

tab: 'ask' | 'share' | 'job' | 'good',

limit: number,

mdrender?: boolean

}

// 获取主题的接口

export interface TOPICS {

id: string,

author_id: string,

tab: string,

content: string,

title: string,

last_reply_at: string,

good: boolean,

top: boolean,

reply_count: number,

visit_count: number,

create_at: string,

author: TOPICSAUTHOR

}

// 作者的类型

export interface TOPICSAUTHOR {

loginname: string,

avatar_url: string

}

复制代码

8.自定义获取方法,结合自己的请求方法返回新的promise对象

// 调用封装方法 返回promise对象 得到获取到的数据

const getTopics = (data: Inter.TOPICSDATA): Promise<Inter.TOPICS> => {

return doRequestAction({

url: Api.topics,

data: data

})

}

复制代码

9. 页面内可以调用getTopics方法拿到我们的数据

import { getTopics } from '../../utils/request/request'

import { TOPICSDATA } from '../../utils/request/inter'

useEffect(()=>{

let data: TOPICSDATA= {

page: 1,

tab: 'ask',

limit: 10

}

getTopics(data).then(res=>console.log(res))

},[])

复制代码

至此,一个简易的封装就完美的结束了,但是在实际开发中为了自己的便利,我们会封装很多经常使用到的参数,这里只是提供一个封装思维,具体还需要在大家的项目中去思考怎么才能去优化代码。

10.总结

知识点

  • es6语法: ...展开运算, 解构赋值, promise

  • ts:类型声明, 可选项, type , any类型 ,单个类型定义

  • 封装思维,文件拆分