Vue3写一个面向对象插件系列4(使用篇4)

1,940 阅读5分钟

背景

创作背景纯粹是因为本人喜欢面向对象风格,并不是说其他风格不好,无意挑起风格流之争,不喜欢的道友求放过,我的目标是兼容现有的vue3的项目,也就是说可以在现有的项目中也可以使用。

HTTP

在现代前端开发中与后端服务器进行数据交互时,使用合适的工具和策略是至关重要的。Vue 框架为我们提供了强大的工具来简化 HTTP 请求和数据处理,其中 HttpService 类和自定义的请求处理函数 useRequest 是其中两个重要的组成部分。通过这些工具,我们能够更加高效地与后端 API 进行通信,同时还能够在数据处理过程中实现更多的灵活性和控制。

@Component({
    template: `
    <template v-request="(isFetching, error, data) in $request(http.getuserlist)">
      <div v-if="isFetching">isFetching</div>
      <div v-else-if="error">{{error}}</div>
      <div v-else-if="data">{{data}}</div>
    </template>
    <button @click="httpRequest()">执行http请求<button>
    <input v-model="username" placeholder="输入用户名搜索"/>
    `
})
export default class OOPDemo implements LifecycleHook {
    username = ref('');
    constructor(public http: HttpSevice) {
    }
    
    async httpRequest() {
        await this.http.getUserList<User[]>();
    }
    
    onSetup() {
      useRequest(([username]: [string]) => this.http.getUserList<User[]>(username), [this.username])
    }
}
  • $request 模板指令

v-request在vue中并不支持,所以经过编译之后才能使用,而且vscode也不会有提示,需要后面工具篇中写的配套vscode插件使用。 我们使用了自定义的 Vue 模板指令 $request 来处理 HTTP 请求的状态和数据。在示例中,模板指令的语法如下:

<template v-request="(isFetching, error, data) in $request(http.getUserList)">
  <!-- 根据请求状态展示不同的内容 -->
</template>
  • useRequest 不同用法

在我们的示例中,我们使用了 useRequest 函数来进行 HTTP 请求的发起和数据处理。该函数具有不同的用法,我们将逐一解释这些用法:

  1. 第二个参数为数组
onSetup() {
    useRequest(([username]) => this.http.getUserList<User[]>(username), [this.username])
}

这种用法中,useRequest 函数接受一个请求函数和一个数组作为参数。请求函数会传入数组中的参数,并发起对应的 HTTP 请求。

  1. 第二个参数为 {}
onSetup() {
    useRequest(
        (params: {username: string, age: number}) => this.http.getUserList<User[]>(username),
        {
            username: this.username,
            age: this.age
        }
    )
}

在这个例子中,我们传递了一个包含多个参数的对象作为 useRequest 的第二个参数,这些参数会传递给请求函数。

  1. 第二个参数为 Ref | ComputedRef | (() => T)
onSetup() {
    useRequest((username: string) => this.http.getUserList<User[]>(username), this.username)
}

在这种情况下,useRequest 函数的第二个参数是一个 RefComputedRef 或函数,这个参数的值会作为请求函数的参数传递。

  1. 第一个参数为 rxjs操作符
  • 节流

    节流是一种限制事件触发频率的策略,确保在一定时间间隔内只执行一次触发的操作。它适用于事件可能在短时间内频繁触发的情况,例如用户连续快速点击按钮或滚动页面。在节流策略下,如果事件在时间间隔内再次触发,操作会被忽略,直到过了设定的时间间隔后才会再次执行。

    使用 throttleTime 操作符,可以设置一定的时间间隔,确保在该时间间隔内只有一个请求被发起。

    onSetup() {
        useRequest(
            throttleTime(1000),
            (username: string) => this.http.getUserList<User[]>(username),
            this.username,
        )
    }
    
  • 防抖

    防抖是一种事件触发策略,通过设定一个延迟时间,在该时间内只有在事件触发后等待期过去后没有新的事件触发,才会执行操作。它适用于在事件触发后,等待用户停止操作一段时间后再执行操作的场景。例如,在实时搜索框中,用户输入字母后,可能希望等待一段时间后才发送搜索请求,以避免用户连续输入时频繁发送请求。

    使用 debounceTime 操作符,可以设置一个延迟时间,在该时间内如果有新请求到达,则会取消之前的请求,只发起最后一次请求。

    onSetup() {
        useRequest(
            debounceTime(1000),
            (username: string) => this.http.getUserList<User[]>(username),
            this.username,
        )
    }
    
  • rxjs操作符

    您可以使用 pipe 函数来将多个操作符串联起来,以实现更复杂的请求处理。例如,您可以使用 map 操作符来对请求参数进行转换

    onSetup() {
        useRequest(
            pipe(map((username: string) => `[${username}]`)),
            // 这里username已经被转换成了`[${username}]`
            (username: string) => this.http.getUserList<User[]>(username),
            this.username,
        )
    }
    
  • HttpSevice

该类是用于发起 HTTP 请求的服务。这个类使用了一些装饰器来定义不同的请求方法,如 GET、POST 和 UPDATE。这些请求方法会通过装饰器来指定请求的路径、参数和返回值类型。下面是这个类的具体代码:

@Injectable({
  apiPrefix: 'user'
})
class HttpService {
  @GET()
  async getUserList(
    @Query() query: Partial<{ username: string; age: number }>
  ): Promise<ApiResult<User[]>> {
    const users = pickEntity<User[]>() ?? []
    // 在这里后处理相应数据,模板中的数据也会相应改变
    replaceEntity(users.forEach(user => user.age > 50))
    return apiResult()
  }

  @GET(':id')
  async getUser(@Param('id') id: number): Promise<ApiResult<User>> {
    const user = pickEntity<User>() ?? {}
    // 在这里可以后处理相应数据,模板中的数据也会相应改变
    Object.assign(user, { 附加字段: '' })
    return apiResult()
  }

  @POST()
  async createUser(
    @Body() body: Partial<{ username: string; age: number }>
  ): Promise<ApiResult<User>> {
    return apiResult()
  }

  @UPDATE(':id')
  async updateUser(@Param('id') id: number): Promise<ApiResult<User>> {
    return apiResult()
  }
}

在这个类中,我们定义了几个不同的请求方法,每个方法都有相应的装饰器来指定请求的路径和参数。我们可以看到,在这些请求方法内部,我们可以执行相应的操作,并对返回的响应数据进行后处理。这些处理后的数据将影响到模板中的数据显示。

这个 HttpService 类在整个应用中负责与后端 API 的通信,根据不同的请求方法执行不同的操作,并将处理后的数据返回给模板以供展示。

总结

在本文中,我们介绍了如何使用 HttpService 类和自定义的请求处理函数 useRequest 来处理 Vue 应用中的 HTTP 请求和数据响应。我们还展示了如何使用 RxJS 操作符进行数据处理,以及如何利用不同的请求策略来优化用户体验。这些技术将有助于您更好地与后端 API 进行通信,并实现更灵活、高效的前端开发。

未完待续

我也将考虑为这些工具开发适用于 WebStorm,vscode 的插件,以提供更好的开发体验和工作效率。通过插件,您可以在编辑器中获得更多的提示、自动补全和错误检查,从而更加方便地使用这些工具。

请继续关注我后续的内容,我将会不断为您带来更多深入的介绍和实际示例,帮助您更好地掌握并应用这些前端开发工具。如果您对这些内容有任何疑问或建议,欢迎随时与我联系,我将会非常乐意为您提供帮助。让我们一起迈向更高效、更优质的前端开发之路!