九、用户页面
该模块作为学生作业,不讲解,仅供源码参考。
创建组件并配置路由
1、创建 views/user/index.vue
<template>   <div class="user-container">用户页面</div> </template>
  <script> export default {   name: 'UserPage',   components: {},   props: {},   data () {     return {}   },   computed: {},   watch: {},   created () {},   mounted () {},   methods: {} } </script>
  <style scoped></style>
 
   | 
 
2、配置到根路由
{   path: '/user/:userId',   name: 'user',   component: () => import('@/views/user') }
  | 
 
最后访问 /user/用户ID 测试。
页面布局
<template>   <div class="user-container">          <van-nav-bar       class="page-nav-bar"       left-arrow       title="用户名"       @click-left="$router.back()"     ></van-nav-bar>     
      <div class="user-info">       <div class="base-info">         <van-image           class="avatar"           round           fit="cover"           src="https://img.yzcdn.cn/vant/cat.jpeg"         />         <div class="right-area">           <div class="stats-wrap">             <div class="stats-item">               <span class="count">66</span>               <span class="text">发布</span>             </div>             <div class="stats-item">               <span class="count">88</span>               <span class="text">关注</span>             </div>             <div class="stats-item">               <span class="count">28</span>               <span class="text">粉丝</span>             </div>             <div class="stats-item">               <span class="count">160</span>               <span class="text">获赞</span>             </div>           </div>           <van-button class="follow-btn">关注</van-button>         </div>       </div>       <div class="label-info">         <div class="bio-wrap">           <span class="label">简介:</span>           <span class="text">这是用户简介</span>         </div>       </div>     </div>   </div> </template>
  <script> export default {   name: 'UserIndex',   components: {},   props: {     userId: {       type: [Number, String, Object],       required: true     }   },   data () {     return {}   },   computed: {},   watch: {},   created () {},   mounted () {},   methods: {} } </script>
  <style scoped lang="less"> .user-container {   .user-info {     background-color: #fff;     padding: 25px 32px;     .base-info {       display: flex;       margin-bottom: 25px;       .avatar {         width: 155px;         height: 155px;         margin-right: 62px;       }     }     .label-info {       font-size: 25px;       .bio-wrap {         .label {           color: #646263;         }         .text {           color: #212121;         }       }     }   }   .right-area {     flex: 1;     display: flex;     flex-direction: column;     justify-content: space-evenly;     .stats-wrap {       display: flex;       justify-content: space-between;       .stats-item {         display: flex;         flex-direction: column;         justify-content: center;         align-items: center;         .count {           font-size: 26px;           color: #0d0a10;         }         .text {           font-size: 21px;           color: #9c9b9d;         }       }     }     .follow-btn {       width: 289px;       height: 55px;       line-height: 55px;       background-color: #6bb5ff;       color: #fff;       border: none;     }   } } </style>
 
   | 
 
<template>   <div class="user-container">          <van-nav-bar title="黑马头条号" left-arrow />     
           <div class="user-info-container">       <div class="row1">         <van-image           class="col1"           fit="cover"           round           src="https://img.yzcdn.cn/vant/cat.jpeg"         />         <div class="col2">           <div class="row1">             <div class="item">               <div class="count">123</div>               <div class="text">发布</div>             </div>             <div class="item">               <div class="count">123</div>               <div class="text">关注</div>             </div>             <div class="item">               <div class="count">123</div>               <div class="text">粉丝</div>             </div>             <div class="item">               <div class="count">123</div>               <div class="text">获赞</div>             </div>           </div>           <div class="action">             <van-button               type="primary"               size="small"             >私信</van-button>             <van-button               type="default"               size="small"             >编辑资料</van-button>           </div>         </div>       </div>       <div class="intro-wrap">         <div>           <span>认证:</span>           <span>用户的认证信息</span>         </div>         <div>           <span>简介:</span>           <span>用户的简介信息</span>         </div>       </div>     </div>     
              </div> </template>
  <script> export default {   name: 'UserPage',   components: {},   props: {},   data () {     return {}   },   computed: {},   watch: {},   created () {},   mounted () {},   methods: {} } </script>
  <style scoped lang="less"> .user-container {   font-size: 14px;   .user-info-container {     padding: 12px;     background-color: #fff;     margin-bottom: 10px;     >.row1 {       display: flex;       justify-content: space-between;       align-items: center;       margin-bottom: 10px;       .item {         text-align: center;         .text {           font-size: 12px;         }       }       >.col1 {         width: 80px;         height: 80px;       }       >.col2 {         display: flex;         flex-direction: column;         justify-content: space-evenly;         width: 70%;         height: 80px;         padding: 0 12px;         >.row1 {           display: flex;           justify-content: space-between;         }         .action {           display: flex;           justify-content: space-between;           .van-button {             width: 45%;           }         }       }     }   } } </style>
 
   | 
 
展示用户信息
步骤:
1、在 api/user.js 中添加获取指定用户信息的数据接口
 export const getUserById = userId => {   return request({     method: 'GET',     url: `/app/v1_0/users/${userId}`   }) }
 
  | 
 
2、在用户页面中请求获取数据
+ import { getUserById } from '@/api/user'
  export default {   name: 'UserPage',   components: {},   props: {},   data () {     return { +      user: {}      }   },   computed: {},   watch: {},   created () { +    this.loadUser()   },   mounted () {},   methods: { +++    async loadUser () {       try {         const { data } = await getUserById(this.$route.params.userId)         this.user = data.data       } catch (err) {         console.log(err)         this.$toast('获取用户数据失败')       }     }   } }
  | 
 
3、模板绑定
用户关注
展示用户文章列表
列表组件
<van-list   v-model="loading"   :finished="finished"   finished-text="没有更多了"   @load="onLoad" >   <van-cell     v-for="item in list"     :key="item"     :title="item"   /> </van-list> export default {   data() {     return {       list: [],       loading: false,       finished: false     };   },
    methods: {     onLoad() {       // 异步更新数据       setTimeout(() => {         for (let i = 0; i < 10; i++) {           this.list.push(this.list.length + 1);         }         // 加载状态结束         this.loading = false;
          // 数据全部加载完成         if (this.list.length >= 40) {           this.finished = true;         }       }, 500);     }   } }
   | 
 
分析列表组件使用
List 的运行机制是什么?
List 会监听浏览器的滚动事件并计算列表的位置,当列表底部与可视区域的距离小于offset时,List 会触发一次 load 事件。
   | 
 
为什么 List 初始化后会立即触发 load 事件?
List 初始化后会触发一次 load 事件,用于加载第一屏的数据,这个特性可以通过`immediate-check`属性关闭。
   | 
 
为什么会连续触发 load 事件?
如果一次请求加载的数据条数较少,导致列表内容无法铺满当前屏幕,List 会继续触发 load 事件,直到内容铺满屏幕或数据全部加载完成。因此你需要调整每次获取的数据条数,理想情况下每次请求获取的数据条数应能够填满一屏高度。
   | 
 
loading 和 finished 分别是什么含义?
List有以下三种状态,理解这些状态有助于你正确地使用List组件:
- 非加载中,
loading为false,此时会根据列表滚动位置判断是否触发load事件(列表内容不足一屏幕时,会直接触发) 
- 加载中,
loading为true,表示正在发送异步请求,此时不会触发load事件 
- 加载完成,
finished为true,此时不会触发load事件 
在每次请求完毕后,需要手动将loading设置为false,表示本次 load 加载结束
使用 float 布局后一直触发加载?
若 List 的内容使用了 float 布局,可以在容器上添加van-clearfix类名来清除浮动,使得 List 能正确判断元素位置
   | 
 
展示文章列表
1、封装获取用户文章列表的数据接口
 
  export const getArticlesByUser = (userId, params) => {   return request({     method: 'GET',     url: `/app/v1_0/users/${userId}/articles`,     params   }) }
 
  | 
 
2、在用户页面中请求获取数据
import { getUserById } from '@/api/user' + import { getArticlesByUser } from '@/api/article'
  export default {   name: 'UserPage',   components: {},   props: {},   data () {     return {       user: {},        list: [],        loading: false,        finished: false,  +      page: 1      }   },   computed: {},   watch: {},   created () {     this.loadUser()   },   mounted () {},   methods: {     async loadUser () {       try {         const { data } = await getUserById(this.$route.params.userId)         this.user = data.data       } catch (err) {         console.log(err)         this.$toast('获取用户数据失败')       }     },
  +++    async onLoad () {              const { data } = await getArticlesByUser(this.$route.params.userId, {         page: this.page,          per_page: 20        })
                                    const { results } = data.data       this.list.push(...results)
               this.loading = false
               if (results.length) {         this.page++        } else {         this.finished = true        }     }   } }
  |