首页 > 其他分享 >前端【uniapp】03-uniapp【练习项目 · 神领物流】

前端【uniapp】03-uniapp【练习项目 · 神领物流】

时间:2024-04-22 20:37:51浏览次数:26  
标签:uniapp const 登录 03 app 接口 uni import 神领

uni-app(神领物流)项目实战

学习目标:

  • 能够对 Pinia 进行初始化操作

  • 掌握创建 Store 及数据操作的步骤

  • 能够对 Pinia 数据进行持久化的处理

  • 掌握 uniForm 表单验证的使用方法

  • 能够根据业务需求配置请求/响应拦截器

一、【神领物流】项目启动

  本节的主要任务是获取项目的静态页面、配置基本的网络请求和公共方法的封装。

1、拉取代码

1 # 拉取仓库代码
2 git clone https://gitee.com/lotjol/shenling-driver.git

  将目录中的 .git 删除,也可以在删除 .git 目录,重新初始化仓库自行练习 Git 的使用。 拿到代码后打开 HBuilderX以导入的方式打开项目(也可以通过拖入的方式打开项目):

  

关于该项目大家需要了解的是配置了 3 个分包:

  • subpkg_message 对应消息的模板的内容

  • subpkg_task 对应任务模块的内容

  • subpkg_user 对应用户模块的内容

  在 H5 端启动项目可以看到项目当前只是完成了静态页面部分的开发,数据接口与业务逻辑部分都尚未实现,这也是接下来我们即将学习的内容。

2、公共封装

2.1 网络请求

  在 uni-app 中通过 uni.request 发起网络请求,在实际的应用中需要结合一些业务场景进行二次封装,比如配置 baseURL、拦截器等,社区有许多封装好的库,我们在项目中可以拿过来直接使用。

  uni-app-fetch 是对 uni.request 的封装,通过 npm 来安装该模块

1 # 安装 uni-app-fetch 模块
2 npm install uni-app-fetch

  然后根据自身的业务需求来配置 uni-app-fetch

 1 // apis/uni-fetch.js
 2 ​
 3 // 导入安装好的 uni-app-fetch 模块
 4 import { createUniFetch } from 'uni-app-fetch'
 5 ​
 6 // 配置符合自身业务的请求对象
 7 export const uniFetch = createUniFetch({
 8     loading: { title: '正在加载...' },
 9     baseURL: 'https://slwl-api.itheima.net',
10     intercept: {
11         // 请求拦截器
12         request(options) {
13             // 后续补充实际逻辑
14       return options
15         },
16         // 响应拦截器
17         response(result) {
18             // 后续补充实际逻辑
19       return result
20         },
21     },
22 })

  uni-app-fetch 更详细的使用文档在这里,它的使用逻辑是仿照 axios 来实现的,只是各别具体的用法稍有差异,在具体的应用中会给大家进行说明。

  • loading 是否启动请求加载提示

  • baseURL 配置请求接口的基地址

  • intercept 配置请求和响应拦截器

  配置完成后到项目首页(任务)测试是否请求能够发出,在测试时需要求【神领物流】全部接口都需要登录才能访问到数据,因此在测试请求时只要能发出请求即可,不关注返回结果是否有数据。

1 <!-- pages/task/index.vue -->
2 <script setup>
3   // 导入根据业务需要封装好的网络请求模块
4     import { uniFetch } from '@/apis/uni-fetch'
5     // 不关注请求结果是否有数据
6     uniFetch({
7         url: '/driver/tasks/list',
8     })
9 </script>

  神领物流接口文档地址在这里

2.2 轻提示

  为了提升用户的体验,在项目的运行过程中需要给用户一些及时的反馈,比如数据验证错误、接口调用失败等,uni-app 中通过调用 uni.showToast 即可实现,但为了保证其使用的便捷性咱们也对它稍做封装处理。

 1 // utils/utils.js
 2 ​
 3 /**
 4  * 项目中会用的一系列的工具方法
 5  */
 6 ​
 7 export const utils = {
 8     /**
 9      * 用户反馈(轻提示)
10      * @param {string} title 提示文字内容
11      * @param {string} icon 提示图标类型
12      */
13     toast(title = '数据加载失败!', icon = 'none') {
14         uni.showToast({
15             title,
16             icon,
17             mask: true,
18         })
19     }
20 }
21 ​
22 // 方便全局进行引用
23 uni.utils = utils

  在项目入口 main.js 中导入封装好的工具模块

1 // main.js
2 import App from './App'
3 import '@/utils/utils'
4 ​
5 // 省略了其它部分代码...

  到项目中测试工具方法是否可用,还是在首页面(task)中测试

 1 // pages/task/index.vue
 2 <script setup>
 3   // 导入根据业务需要封装好的网络请求模块
 4     import { uniFetch } from '@/apis/uni-fetch'
 5     // 不关注请求结果是否有数据
 6     uniFetch({
 7         url: '/driver/tasks/list'
 8     }).then((result) => {
 9     if(result.statusCode !== 200) uni.utils.toast()
10   })
11 </script>

  通过上述代码的演示我们还可以证实一个结论:uni-app-fetch 返加的是 Promise 对象,将来可配合 async/await 来使用。

二、【神领物流】用户登录

  【神领物流】所有接口的调用都必须是登录状态才可以,因此我们要实现的第一个功能模块就是用户的登录。

1、Pinia 状态管理

  用户登录后需要将登录状态(token)信息记录下来,在 Vue2 的项目中使用 Vuex3 来实现,但是在 Vue3 的项目中需要使用 Vuex4 或者 Pinia 来实现。
  Pinia 是 Vue 专属于状态管理库,是 Vuex 状态管理工具的替代品,其具有一个特点:
  • 提供了更简单的 API(去掉了 mutation)
  • 提供组合式风格的 API
  • 去掉了 modules 的概念,每一个 store 都是独立的模块
  • 配合 TypeScript 更加友好,提供可靠的类型推断

1.1 安装 Pinia

1 # 安装 pinia 到项目当中
2 npm install pinia

  在这里大家需要注意一下,在 uni-app 中内置集成了 Pinia 的支持,因此可以省略掉安装这个步骤,但如果是在非 uni-app 的 Vue3 项目使用 Pinia 时必须要安装后再使用。

1.2 Pinia 初始化

 1 // main.js
 2 import { createSSRApp } from 'vue'
 3 // 引入 Pinia
 4 import { createPinia } from 'pinia'
 5 ​
 6 import App from './App'
 7 import '@/utils/utils'
 8 ​
 9 export function createApp() {
10   const app = createSSRApp(App)
11 ​
12   // 实例化Pinia
13   const pinia = createPinia()
14   // 传递给项目应用
15   app.use(pinia)
16 ​
17   return { app }
18 }

1.3 定义 Store

  在 Vuex 中我们已经知道 了 store 本质上就是在【定义数据】及【处理数据】的方法,在 Pinia 中 store 也是用来【定义数据】和【处理数据】的方法的,所不同的是定义的方式不同。

  • ref() 就是 state
  • computed 就是 getters
  • function() 就是 actions
 1 // stores/counter.js
 2 import { defineStore } from 'pinia'
 3 import { ref } from 'vue'
 4 ​
 5 export const useCounterStore = defineStore('counter', () => {
 6   // 状态数据(相当于 state)
 7   const count = ref(0)
 8   // 定义方法(相当于 actions)
 9   function increment() {
10     count.value++
11   }
12 ​
13   function decrement() {
14     count.value--
15   }
16 ​
17   // 一定要将定义的数据和方法返回
18   return { count, increment, decrement }
19 })

  接下来将定义好的状态数据应用于 Vue 的组件中,只需要将将 Pinia 定义的 Store 当成普通模块来使用就可以了,详见下面代码:

 1 <!-- pages/pinia/index.vue -->
 2 <script setup>
 3   import { useCounterStore } from '@/stores/counter'
 4   // 获取 store 对象
 5   const store = useCounterStore()
 6 </script>
 7 <template>
 8   <view class="counter">
 9     <button @click="store.decrement" class="button" type="primary">-</button>
10     <input class="input" v-model="store.count" type="text" />
11     <button @click="store.increment" class="button" type="primary">+</button>
12   </view>
13 </template>

1.4 storeToRefs

  使用 storeToRefs 函数可以辅助保持数据(state + getter)的响应式结构,即对数据进行解构处理后仍然能保持响应式的特性。

 1 <!-- pages/pinia/index.vue -->
 2 <script setup>
 3   import { storeToRefs } from 'pinia'
 4   import { useCounterStore } from '@/stores/counter'
 5 ​
 6   // 获取 store 对象
 7   const store = useCounterStore()
 8   const { count } = storeToRefs(store)
 9   const { increment, decrement } = store
10 </script>
11 <template>
12   <view class="counter">
13     <button @click="decrement" class="button" type="primary">-</button>
14     <input class="input" v-model="count" type="text" />
15     <button @click="increment" class="button" type="primary">+</button>
16   </view>
17 </template>

1.5 持久化

  在实际的开发过程中有部分的业务数据需要长时间的保存,即所谓的持久化,例如标识用户登录状态的 token 通常需要长时间的保存起来,在 Pinia 中管理数据状态的同时要实现数据的持久化,需要引入pinia-plugin-persistedstate 插件

1 # 安装 pinia-plugin-persistedstate 插件
2 npm i pinia-plugin-persistedstate

  分成3个步骤来使用 pinia-plugin-persistedstate

  1. 将插件添加到 pinia 实例上

 1 // main.js
 2 import { createSSRApp } from 'vue'
 3 import { createPinia } from 'pinia'
 4 import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
 5 ​
 6 // 省略中间部分代码...
 7 ​
 8 export function createApp() {
 9   const app = createSSRApp(App)
10   
11   // 实例化Pinia
12   const pinia = createPinia()
13   // Pinia 持久化插件
14   pinia.use(piniaPluginPersistedstate)
15     
16   // 省略部分代码...
17 }
  1. 配置需要持久化的数据,创建 Store 时,将 persist 选项设置为 true

 1 import { defineStore } from 'pinia'
 2 import { ref } from 'vue'
 3 ​
 4 export const useCounterStore = defineStore('counter', () => {
 5   // 状态数据(相当于 state)
 6   const count = ref(0)
 7   
 8     // 省略部分代码...
 9 ​
10   // 一定要将定义的数据和方法返回
11   return { count, increment, decrement }
12 }, {
13   persist: {
14     paths: ['count'],
15   }
16 })

  当把 persist 设置为 true 表示当前 Store 中全部数据都会被持久化处理, 除此之外还可以通过 paths 来特别指定要持久化的数据。

  1. 自定义存储方法(针对 uni-app的处理)

  小程序中和H5中实现本地存储的方法不同,为了解决这个问题需要自定义本地存储的逻辑。

 1 // stores/persist.js
 2 import { createPersistedState } from 'pinia-plugin-persistedstate'
 3 export const piniaPluginPersistedstate = createPersistedState({
 4   key: (id) => `__persisted__${id}`,
 5   storage: {
 6     getItem: (key) => {
 7       return uni.getStorageSync(key)
 8     },
 9     setItem: (key, value) => {
10       uni.setStorageSync(key, value)
11     },
12   },
13 })

  使用 uni-app 的 API uni.getStorageSyncuni.setStorageSync 能够同时兼容 H5、小程序以及 App,然后需要调整原来在 main.js 中的部分代码

 1 // main.js
 2 import { createSSRApp } from 'vue'
 3 import { createPinia } from 'pinia'
 4 // import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
 5 import { piniaPluginPersistedstate } from '@/stores/persist'
 6 ​
 7 // 省略中间部分代码...
 8 ​
 9 export function createApp() {
10   const app = createSSRApp(App)
11   
12   // 实例化Pinia
13   const pinia = createPinia()
14   // Pinia 持久化插件
15   pinia.use(piniaPluginPersistedstate)
16     
17   // 省略部分代码...
18 }

2、uniForm 表单验证

  通常在提交表数据时需要对用户填写的内容进行校验,在 uni-app 的扩展组件中提供了关于表单数据验证的功能,我们来学习一下它的使用步骤:

2.1 表单数据

  定义表单的数据,指定 v-model 获取用户的数据

 1 <!-- pages/login/components/account.vue -->
 2 <script setup>
 3   import { ref, reactive } from 'vue'
 4   
 5   // 表单数据
 6   const formData = reactive({
 7     account: '',
 8     password: '',
 9   })
10 </script>
11 <template>
12   <uni-forms class="login-form" :model="formData">
13     <uni-forms-item name="account">
14       <input
15         type="text"
16         v-model="formData.account"
17         placeholder="请输入账号"
18         class="uni-input-input"
19         placeholder-style="color: #818181"
20       />
21     </uni-forms-item>
22     ...
23   </uni-forms>
24 </template>

2.2 验证规则

  uni-app 的表单验证功能需要单独定义验证的规则:

 1 <!-- pages/login/components/account.vue -->
 2 <script setup>
 3   import { ref, reactive } from 'vue'
 4   
 5   // 表单数据
 6   const formData = reactive({
 7     account: '',
 8     password: '',
 9   })
10   
11   // 定义表单数据验证规则
12   const accountRules = reactive({
13     account: {
14       rules: [
15         { required: true, errorMessage: '请输入登录账号' },
16         { pattern: '^[a-zA-Z0-9]{6,8}$', errorMessage: '登录账号格式不正确' },
17       ],
18     },
19     password: {
20       rules: [
21         { required: true, errorMessage: '请输入登录密码' },
22         { pattern: '^\\d{6}$', errorMessage: '登录密码格式不正确' },
23       ],
24     },
25   })
26 </script>
27 <template>
28   <uni-forms class="login-form" :rules="accountRules" :model="formData">
29     <uni-forms-item name="account">
30       <input
31         type="text"
32         v-model="formData.account"
33         placeholder="请输入账号"
34         class="uni-input-input"
35         placeholder-style="color: #818181"
36       />
37     </uni-forms-item>
38     ...
39   </uni-forms>
40 </template>

  在定义 accountRules 时,对象中的 key 对应的是待验证的数据项目,如 account 表示要验证表单数据 accountrules 用来指验证的条件和错误信息提示。

2.3 触发验证

  调用 validate 方法触发表单验单

 1 <!-- pages/login/components/account.vue -->
 2 <script setup>
 3   import { ref, reactive } from 'vue'
 4   
 5     // 表单元素的 ref 属性
 6   const accountForm = ref()
 7   
 8   // 表单数据
 9   const formData = reactive({
10     account: '',
11     password: '',
12   })
13   
14   // 定义表单数据验证规则
15   const accountRules = reactive({
16     account: {
17       rules: [
18         { required: true, errorMessage: '请输入登录账号' },
19         { pattern: '^[a-zA-Z0-9]{6,8}$', errorMessage: '登录账号格式不正确' },
20       ],
21     },
22     password: {
23       rules: [
24         { required: true, errorMessage: '请输入登录密码' },
25         { pattern: '^\\d{6}$', errorMessage: '登录密码格式不正确' },
26       ],
27     },
28   })
29   
30   // 监听表单的提交
31   async function onFormSubmit() {
32     try {
33       // 验证通过
34       const formData = await accountForm.value.validate()
35       // 表单的数据
36       console.log(formData)
37     } catch (err) {
38       // 验证失败
39       console.log(err)
40     }
41   }
42 </script>
43 <template>
44   <uni-forms
45     class="login-form"
46     ref="accountForm"
47     :rules="accountRules"
48     :model="formData"
49   >
50     <uni-forms-item name="account">
51       <input
52         type="text"
53         v-model="formData.account"
54         placeholder="请输入账号"
55         class="uni-input-input"
56         placeholder-style="color: #818181"
57       />
58     </uni-forms-item>
59     ...
60     <button @click="onFormSubmit" class="submit-button">登录</button>
61   </uni-forms>
62 </template>

3、登录实现

  完整的登录功能包含也以下几个小的步骤,我们一步一步来实现。

3.1 调用接口

  在验证用户数据通过后就可以调用接口来完成登录的操作了,登录接口的文档地址在这里

  为了方便接口调用的管理和维护我们将接口调用的逻辑封到独立的模块中

 1 // apis/user.js
 2 // 引入网络请求模块
 3 import { uniFetch } from './uni-fetch'
 4 export default {
 5   /**
 6    * @param {Object} data 用户账号和用户密码
 7    */
 8   login(data) {
 9     if (!data.account || !data.password) return
10     // 根据接口文档来调用接口
11     return uniFetch.post('/driver/login/account', data)
12   }
13 }

  接下来就可以在用户点击登录时调用模块中封装好的 login 方法了

 1 <!-- pages/login/components/account.vue -->
 2 <script setup>
 3   import { ref, reactive } from 'vue'
 4   import userApi from '@/apis/user'
 5   
 6   // 中间部分代码省略了...
 7   
 8   async function onFormSubmit() {
 9     try {
10       // 验证表单数据且通过
11       const formData = await accountForm.value.validate()
12       // 调用登录接口
13       const { code } = await userApi.login(formData)
14       // 记录用户登录成功后的状态
15     } catch (err) {
16       // 验证失败
17       console.log(err)
18     }
19   }
20 </script>

3.2 拦截器

  用户登录成功后,再次调用其它的接口时就需要将登录状态通过自定义请求头的方式传递给接口服务器了,这个功能我们通过请求拦截器来实现,分成两个步骤来实现:

  1. 通过 Pinia 来记录并持久化 token

 1 // stores/users.js
 2 import { defineStore } from 'pinia'
 3 import { ref } from 'vue'
 4 ​
 5 export const useUserStore = defineStore('user', () => {
 6   // 登录状态
 7   const token = ref('')
 8 ​
 9   return { token }
10 }, {
11   persist: {
12     paths: ['token'],
13   },
14 })

  上述代码中定义了与用户(user)相关的 Store,并定义了数据 token,用来记录用户的登录状态。

  接下来在调用登录接口成功后 token 通过 Pinia 存储起来

 1 <!-- pages/login/components/account.vue -->
 2 <script setup>
 3   import { ref, reactive } from 'vue'
 4   import userApi from '@/apis/user'
 5   import { useUserStore } from '@/stores/user'
 6   const userStore = useUserStore()
 7   
 8   // 中间部分代码省略了...
 9   
10   async function onFormSubmit() {
11     try {
12       // 验证表单数据且通过
13       const formData = await accountForm.value.validate()
14       // 调用登录接口
15       const { code } = await userApi.login(formData)
16       
17       // 检测接口是否调用成功
18       if (code !== 200) return uni.utils.toast('登录失败,请重试!')
19       // 持久化存储用户登录状态
20       userStore.token = data
21       
22     } catch (err) {
23       // 验证失败
24       console.log(err)
25     }
26   }
27 </script>
  1. 配置请求拦截器

  登录成功后,当再次调用其它接口里需要将用户的登录状态以自定义头信息的方式发送到服务端,配置请求拦截器来实此功能。

 1 // apis/uni-fetch.js
 2 // 导入安装好的 uni-app-fetch 模块
 3 import { createUniFetch } from 'uni-app-fetch'
 4 import { useUserStore } from '@/stores/user'
 5 ​
 6 // 配置符合自身业务的请求对象
 7 export const uniFetch = createUniFetch({
 8   loading: { title: '正在加载...' },
 9   baseURL: 'https://slwl-api.itheima.net',
10   intercept: {
11     // 请求拦截器
12     request(options) {
13       const userState = useUserStore()
14       // 全局公共头信息
15       const defaultHeaders = {
16         Authorization: userState.token,
17       }
18       // 自定义头信息(token)
19       options.header = Object.assign({}, defaultHeaders, options.header, )
20 ​
21       return options
22     },
23     // 响应拦截器
24     response({ data }) {
25       // 过滤多余的数据
26       return data
27     },
28   },
29 })

  回到首页面(task)当中,之前测试过任务列表接口的调用,现在给它传必须的参数 statuspagepageSize 然后可以看到接口能返回数据了,原因就在于自定义头信息 Authorization 携带了用户的登录状态 token,也就证明了咱们关于请求拦截器的配置生效了。

 1 <!-- pages/task/index.vue -->
 2 <script>
 3   import { ref } from 'vue'
 4   import { uniFetch } from '@/apis/uni-fetch'
 5 ​
 6   uniFetch({
 7     url: '/driver/tasks/list',
 8     // 传入该接口必要的参数
 9     data: { status: 1, page: 1, pageSize: 10 },
10   }).then((result) => {
11     if (result.statusCode) uni.utils.toast()
12   })
13 </script>

3.3 地址重定向

  与登录相关的重定向有两个方面,一是用户登录成功后需要到跳转到新页面,另一个是当检测到用户的 token 失效后跳转到登录页生新进行登录,因此我们分成两个步骤来学习。注:当前项目的 token 12个小时后会失效。

  1. 在响应拦截器检测请求响应的状态码是否为 401 ,状态码 401 表示当前 token 失效了,需要重新登录

 1 // apis/uni-fetch.js
 2 // 导入安装好的 uni-app-fetch 模块
 3 import { createUniFetch } from 'uni-app-fetch'
 4 import { useUserStore } from '@/stores/user'
 5 // 定义 tabBar 的路径
 6 const tabBarPagePaths = [
 7   'pages/task/index',
 8   'pages/message/index',
 9   'pages/my/index'
10 ]
11 ​
12 // 配置符合自身业务的请求对象
13 export const uniFetch = createUniFetch({
14   loading: { title: '正在加载...' },
15   baseURL: 'https://slwl-api.itheima.net',
16   intercept: {
17     // 请求拦截器
18     request(options) {
19         // 省略中间部分代码...
20       return options
21     },
22     // 响应拦截器
23     response({ statusCode, data }) {
24       if (statusCode === 401) {
25         // 页面栈
26         const pageStack = getCurrentPages()
27         // 当前页面地址
28         const redirectURL = pageStack[pageStack.length - 1].route
29         // tabBar 页面需要使用 switchTab 跳转
30         const routeType = tabBarPagePaths.includes(redirectURL)
31           ? 'switchTab'
32           : 'redirectTo'
33         
34         return uni.redirectTo({
35           url: `/pages/login/index?routeType=${routeType}&redirectURL=/${redirectURL}`,
36         })
37       }
38       
39       return data
40     },
41   },
42 })

  上述代码需重点需要注意判断调用接口的页面是否为 tabBar 的页面,目的是下个步骤登录成功后能够成功的回跳到当前这个页面中,tabBar 的页面使用 uni.switchTab 跳转,否则使用 wx.redirectTo 跳转。

  1. 当用户登录成功能跳回来原来的页面

 1 <!-- pages/login/components/account.vue -->
 2 <script setup>
 3   import { ref, reactive } from 'vue'
 4   import { onl oad } from '@dcloudio/uni-app'
 5     
 6   // 省略中间部分代码
 7 ​
 8   // 回跳地址
 9   const redirectURL = ref('')
10   // 跳转地址方式
11   const routeType = ref('')
12 ​
13   // 获取地址中的参数
14   onl oad((query) => {
15     redirectURL.value = query.redirectURL
16     routeType.value = query.routeType
17   })
18 ​
19   // 监听表单提交
20   async function onFormSubmit() {
21     try {
22             // 省略部分代码...
23       
24       // 地址重定向或switchTab
25       uni[routeType.value]({ url: redirectURL.value })
26     } catch (err) {
27       // 验证失败
28       console.log(err)
29     }
30   }
31 </script>

三、【神领物流】我的

  我的模块中有 3 个独立的接口调用,需要大家自已来完成。

1、个人信息查询

  个人信息查询即在【我的】页面中展示当前登录司机的个人信息,包括头像、名称、编号。

  接口文档的说明在这里,分成 2 个步骤来实现:

  1. 定义接口调用的方法,在 apis/user.js 中新增获取司机信息的接口

 1 // apis/user.js
 2 // 引入网络请求模块
 3 import { uniFetch } from './uni-fetch'
 4 ​
 5 export default {
 6     // 省略中间部分代码...
 7   /**
 8    * 个人资料
 9    */
10   profile() {
11     return uniFetch.get('/driver/users')
12   },
13 }
  1. 在【我的】页面中获取数据并渲染

 1 <!-- pages/my/index.vue -->
 2 <script setup>
 3   import { ref } from 'vue'
 4   import { onl oad } from '@dcloudio/uni-app'
 5   import userApi from '@/apis/user'
 6 ​
 7   // 用户信息
 8   const userProfile = ref({})
 9 ​
10   onl oad(() => {
11     getUserProfile()
12   })
13 ​
14   // 用户信息接口
15   async function getUserProfile() {
16     try {
17       const { code, data } = await userApi.profile()
18       // 检测接口否调用成功
19       if (code !== 200) return uni.utils.toast()
20       // 渲染请求来的数据
21       userProfile.value = data
22     } catch (err) {
23       console.log(err)
24     }
25   }
26 </script>
27 ​
28 <template>
29   <view class="page-container">
30     <view class="user-profile">
31       <image class="avatar" :src="userProfile.avatar" mode=""></image>
32       <text class="username">{{ userProfile.name }}</text>
33       <text class="no">司机编号:{{ userProfile.phone }}</text>
34       <text class="mobile">手机号码:{{ userProfile.number }}</text>
35     </view>
36         ...
37   </view>
38 </template>

2、任务数据查询

  任务数据查询也是在在【我的】页面中进行展示,展示的内容包括3项,分别是任务总量、完成任务量、运输时程。注:这些数据初始为 0 ,后续开发完【任务】模块后这里的数据会发生更新。

  接口文档的说明在这里,分成 2 个步骤来实现:

  1. 定义接口调用的方法,在 apis/user.js 中新增获取任务数据的接口

 1 // apis/user.js
 2 // 引入网络请求模块
 3 import { uniFetch } from './uni-fetch'
 4 ​
 5 export default {
 6     // 省略中间部分代码...
 7   /**
 8    * 任务数据
 9    * @param {string} year - 任务数据的年份
10    * @param {string} month - 任务数据的月份
11    */
12   task(year, month) {
13     return uniFetch.get('/driver/users/taskReport', { year, month })
14   },
15 }
  1. 在【我的】页面中获取数据并渲染

 1 <!-- pages/my/index.vue -->
 2 <script setup>
 3   import { ref } from 'vue'
 4   import { onl oad } from '@dcloudio/uni-app'
 5   import userApi from '@/apis/user'
 6 ​
 7   // 用户信息
 8   const userProfile = ref({})
 9   // 任务数据
10   const taskInfo = ref({})
11 ​
12   onl oad(() => {
13     getUserProfile()
14     getTaskInfo()
15   })
16 ​
17   // 用户信息接口
18   async function getUserProfile() {
19     try {
20       const { code, data } = await userApi.profile()
21       // 检测接口否调用成功
22       if (code !== 200) return uni.utils.toast()
23       // 渲染请求来的数据
24       userProfile.value = data
25     } catch (err) {
26       console.log(err)
27     }
28   }
29   
30   // 任务数据
31   async function getTaskInfo() {
32     try {
33       const { code, data } = await userApi.task('2023', '07')
34       // 检测接口否调用成功
35       if (code !== 200) return uni.utils.toast()
36       // 渲染请求来的数据
37       taskInfo.value = data
38     } catch (err) {
39       console.log(err)
40     }
41   }
42 </script>
43 ​
44 <template>
45   <view class="page-container">
46     ...
47     <view class="month-overview">
48       <view class="title">本月任务</view>
49       <view class="content">
50         <view class="item">
51           <text class="volumn">{{ taskInfo.taskAmounts }}</text>
52           <text class="label">任务总量</text>
53         </view>
54         <view class="item">
55           <text class="volumn">{{ taskInfo.completedAmounts }}</text>
56           <text class="label">完成任务量</text>
57         </view>
58         <view class="item">
59           <text class="volumn">{{ taskInfo.transportMileage }}</text>
60           <text class="label">运输里程(km)</text>
61         </view>
62       </view>
63     </view>
64     ...
65   </view>
66 </template>

3、车辆信息查询

  查询当前司机所驾驶车辆的相关信息,展示的内容包括车辆照片、车牌号、车型等信息。

  接口文档的说明在这里,分成两个步骤来实现:

  1. 定义接口调用的方法,在 apis/user.js 中新增获取车辆信息的接口

 1 // apis/user.js
 2 // 引入网络请求模块
 3 import { uniFetch } from './uni-fetch'
 4 ​
 5 export default {
 6     // 省略中间部分代码...
 7   /**
 8    * 车辆信息
 9    */
10   truck() {
11     return uniFetch.get('/driver/users/truck')
12   },
13 }
  1. 在【车辆信息】页面中获取数据并渲染

 1 <!-- subpkg_user/truck/index.vue -->
 2 <script setup>
 3   import { ref } from 'vue'
 4   import { onl oad } from '@dcloudio/uni-app'
 5   import userApi from '@/apis/user'
 6 ​
 7   // 车辆信息
 8   const truchInfo = ref({})
 9 ​
10   onl oad(() => {
11     getTruckInfo()
12   })
13 ​
14   // 获取车辆信息
15   async function getTruckInfo() {
16     try {
17       const { code, data } = await userApi.truck()
18       // 检测接口否调用成功
19       if (code !== 200) return uni.utils.toast()
20       // 渲染请求来的数据
21       truchInfo.value = data
22     } catch (err) {
23       console.log(err)
24     }
25   }
26 </script>
27 ​
28 <template>
29   <view class="page-container">
30     <swiper
31       class="truck-pictures"
32       indicator-active-color="#fff"
33       circular
34       indicator-dots
35     >
36       <swiper-item v-for="picture in truchInfo.pictureList" :key="picture.url">
37         <image class="picture" mode="aspectFill" :src="picture.url"></image>
38       </swiper-item>
39     </swiper>
40     <view class="truck-meta">
41       <uni-list :border="false">
42         <uni-list-item
43           :border="false"
44           title="车辆编号"
45           :right-text="truchInfo.id"
46         />
47         <uni-list-item
48           :border="false"
49           title="车辆号牌"
50           :right-text="truchInfo.licensePlate"
51         />
52         <uni-list-item
53           :border="false"
54           title="车型"
55           :right-text="truchInfo.truckType"
56         />
57         <uni-list-item
58           :border="false"
59           title="所属机构"
60           :right-text="truchInfo.currentOrganName"
61         />
62         <uni-list-item
63           :border="false"
64           title="载重"
65           :right-text="truchInfo.allowableLoad"
66         />
67       </uni-list>
68     </view>
69   </view>
70 </template>

标签:uniapp,const,登录,03,app,接口,uni,import,神领
From: https://www.cnblogs.com/wang1001/p/18151440

相关文章

  • 前端【uniapp】02-uniapp【全局文件】【组件【内置、扩展】】【声明周期】【API调用】
    一、uni-app基础知识uni-app是组合了Vue和微信小程序的相关技术知识,要求大家同时俱备Vue和原生小程序的开发基础。1、全局文件在小程序中有全局样式、全局配置等全局性的设置,为此在uni-app中也有一些与之相对应的全局性的文件。uni.scssuni-app项目在运......
  • CF1137F Matches Are Not a Child's Play 题解
    题目链接点击打开链接题目解法参考abruce的非\(lct\)的做法\(compare\)操作是搞笑的,可以转化成求\(u,v\)的\(when\)操作一个结论是编号最大的点一定是最晚删的,不妨令编号最大的点为根,则删除顺序一定是从下往上删的先考虑原树上单个点\(u\)的\(when\)怎么求令......
  • sh003基于springboot的汽车租赁系统
    sh003基于springboot的汽车租赁系统 介绍汽车租赁系统管理员功能主要包括:系统设置管理、用户管理、留言板管理、公告类型管理、公告管理等功能由于本系统的功能模块设计比较全面,所以使得整个汽车租赁系统信息管理的过程得以实现。软件架构推荐使用:谷歌浏览器前台登录页......
  • 'vue-cli-service' 不是内部或外部命令,也不是可运行的程序
    D:\Work\NewProgramm\14)福建附二院后台管理\FujianHospitalTextile\ZR.Vue>yarnrundevyarnrunv1.22.22warningpackage.json:Nolicensefield$setNODE_OPTIONS=--openssl-legacy-provider&vue-cli-serviceserve'vue-cli-service'不是内部或外部命令,也不......
  • OpenEuler22.03 SP3离线安装Docker
    下载Docker离线安装包下载地址:https://download.docker.com/linux/static/stable/下面以安装docker-23.0.5.tgz为例。安装Docker解压docker-23.0.5.tgz[root@mccp~]#tar-zxvfdocker-23.0.5.tgzdocker/docker/docker-proxydocker/containerd-shim-runc-v2docker/ctrdocker......
  • 34天【代码随想录算法训练营34期】第八章 贪心算法 part03 (● 1005.K次取反后最大化
    1005.K次取反后最大化的数组和classSolution:deflargestSumAfterKNegations(self,nums:List[int],k:int)->int:nums.sort(key=lambdax:abs(x),reverse=True)foriinrange(len(nums)):ifnums[i]<0andk>0:......
  • LED车灯IC降压恒流驱动AP5103大功率95%高效率深度调光摩托车灯芯片
    产品描述AP5103是一款效率高,稳定可靠的LED灯恒流驱动控制芯片,内置高精度比较器,固定关断时间控制电路,恒流驱动电路等,特别适合大功率LED恒流驱动。AP5103采用ESOP8封装,散热片内置接SW脚,通过调节外置电流检测的电阻值来设置流过LED灯的电流,支持外加电压线性调光,最大电......
  • SQL+WHERE+别名+过滤的问题 Column 'code' in where clause is ambiguous
    背景有两张表,父表task和子表sub_task,它们使用id关联,并且都有自己的编号code,但是在分页查询子任务列表时,编号需要使用父表编号+子表编号进行拼接(比如,task表编号为zh001,sub_task表编号为01,则页面展示为zh001-01),并且需要根据组成的编号过滤。问题实际项目使用时,sql......
  • 前端【TS】03-typescript【基础】【Pinia】
    介绍 什么是PiniaPinia是Vue的专属的最新状态管理库,是Vuex状态管理工具的替代品 手动添加Pinia到Vue项目1.使用Vite创建一个空的TS+Vue3项目1npmcreatevite@latestvue-pinia-ts----templatevue-ts2.按照官方文档安装pinia到项......
  • 站立会议和燃尽图03
    站立会议和燃尽图03一、小组情况组长:李宏威组员:董泽豪队名:隐约类名二、Scrum例会时间:2024年4月21日出席人员:李宏威,董泽豪要求1工作照片要求2时间跨度2024年4月16日7:00至2024年4月16日7:20共计20分钟要求3地点石家庄铁道大学要求4立会内容包括:(1)未开始......