【Vue】axios实现github案例《大批量搜索github用户》

目录

大批量搜索github用户

分为两部分:1. 搜索框(Search) 2. 用户列表(List)

接口地址:https://api.github.com/search/users?q=xxx

本章节对我有很大的收获, 希望对你也是!!!


本节素材已上传至Gitee:yihaohhh/我爱Vue - Gitee.com

大批量搜索github用户

本节将实现github搜索框搜索后展示搜索到的用户列表

依旧得到本节的素材后就来进行拆分组件

分为两部分:1. 搜索框(Search) 2. 用户列表(List)

App组件:

<template>
  <div class="container">
    <Search/>
    <List/>
  </div>
</template>

<script>
// import 检查非常严格 如果没有该路径的资源就会报错
// 在asserts 里面配置就是要用import进行引入,那么就会进行严格的检查
// bootstrap.css 用到了不存在的资源 所以还是不要在asserts 静态资源里面引入
// import './assets/css/bootstrap.css' 在public的index.html 里面进行引入

import Search from './components/Search.vue'
import List from './components/List.vue'

export default {
  name:'App',
  components:{Search, List}
}

</script>

唯一需要注意的就是当前App组件引入的bootstrap静态资源要在public里面进行引入

然后在public里面的index.html进行引入即可:

  <!-- 引入第三方样式库 -->
  <link rel="stylesheet" href="<%= BASE_URL %>css/bootstrap.css">

import 检查非常严格 如果没有该路径的资源就会报错

在asserts 里面配置就是要用import进行引入,那么就会进行严格的检查bootstrap.css 用到了不存在的资源 所以还是不要在asserts 静态资源里面引入

import './assets/css/bootstrap.css' 在public的index.html 里面进行引入

Search组件:

<template>
  <div>
    <section class="jumbotron">
      <h3 class="jumbotron-heading">Search Github Users</h3>
      <div>
        <input type="text" placeholder="enter the name you search" />&nbsp;<button>Search</button>
      </div>
    </section>
  </div>
</template>

<script>
export default {
  name:'Search'
}
</script>

List组件:

<template>
  <div>
    <div class="row">
      <div class="card">
        <a href="https://github.com/xxxxxx" target="_blank">
          <img src="https://cn.vuejs.org/images/logo.svg" style='width: 100px' />
        </a>
        <p class="card-text">xxxxxx</p>
      </div>
      <div class="card">
        <a href="https://github.com/xxxxxx" target="_blank">
          <img src="https://cn.vuejs.org/images/logo.svg" style='width: 100px' />
        </a>
        <p class="card-text">xxxxxx</p>
      </div>
      <div class="card">
        <a href="https://github.com/xxxxxx" target="_blank">
          <img src="https://cn.vuejs.org/images/logo.svg" style='width: 100px' />
        </a>
        <p class="card-text">xxxxxx</p>
      </div>
      <div class="card">
        <a href="https://github.com/xxxxxx" target="_blank">
          <img src="https://cn.vuejs.org/images/logo.svg" style='width: 100px' />
        </a>
        <p class="card-text">xxxxxx</p>
      </div>
      <div class="card">
        <a href="https://github.com/xxxxxx" target="_blank">
          <img src="https://cn.vuejs.org/images/logo.svg" style='width: 100px' />
        </a>
        <p class="card-text">xxxxxx</p>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name:'List'
}
</script>

<style scoped>
  .album {
    min-height: 50rem;
    /* Can be removed; just added for demo purposes */
    padding-top: 3rem;
    padding-bottom: 3rem;
    background-color: #f7f7f7;
  }

  .card {
    float: left;
    width: 33.333%;
    padding: .75rem;
    margin-bottom: 2rem;
    border: 1px solid #efefef;
    text-align: center;
  }

  .card>img {
    margin-bottom: .75rem;
    border-radius: 100px;
  }

  .card-text {
    font-size: 85%;
  }
</style>

接口地址:https://api.github.com/search/users?q=xxx

这是github官方提供的接口,可以直接拿来用于搜索关键字的用户进行返回

1. 就是要获取搜索框内输入的值 用v-model进行双向绑定

        <input type="text" placeholder="enter the name you search" v-model="keyWord"/>&nbsp;
        <button @click="searchUsers">Search</button>

    data() {
      return {
        keyWord: ''
      }
    },

得到keyWord后就可以直接进行发送请求来得到github的返回值

    methods: {
      searchUsers() {
        axios.get(`https://api.github.com/search/users?q=${this.keyWord}`).then(
          response => {
            console.log('请求成功了', response.data)
          },
          error => {
            console.log('请求失败了', error.message)
          }
        ) 
      }
    }

那么我们只需要得到response.data.items的数组内容传给List组件即可,那么这就是兄弟组件之间的互相通信 1. 全局事件总线 2. 消息的订阅与发布

那么我们就用全局事件总线进行用户存储到List组件内

List组件挂载生命周期钩子,进行绑定事件

  mounted() {
    this.$bus.$on('getUsers', (users) => {
      console.log('我是List组件, 收到了数据:',users)
      this.users = users
    })
  }

Search组件进行触发该事件

      searchUsers() {
        axios.get(`https://api.github.com/search/users?q=${this.keyWord}`).then(
          response => {
            console.log('请求成功了', response.data.items)
            this.$bus.$emit('getUsers', response.data.items)
          },
          error => {
            console.log('请求失败了', error.message)
          }
        ) 
      }

可以看到List组件成功的收到了Search组件传来的消息,并且成功进行保存items数据

那么我们得到当前用户信息后就可以在List组件中进行v-for来渲染用户信息,全部都采用v-bind进行动态绑定即可

  <div class="row">
    <div class="card" v-for="user in users" :key="user.login">
      <a :href="user.html_url" target="_blank">
        <img :src="user.avatar_url" style='width: 100px' />
      </a>
      <p class="card-text">{{user.login}}</p>
    </div>
  </div>
  • 这表示 href 的值 不是字符串常量,而是绑定到 Vue 实例中 user.html_url 的这个值
  • 如果不使用v-bind 那么就会使字符串的样字 不会解析js

动态绑定好后,就可以看看效果!将用户的头像和用户名以及用户的跳转地址都渲染出来了

还可以进一步优化一下,观察上面,在我们进行搜索的时候,会有一段空白期,我们不知道是否使网页卡住还是正在请求中,所以我们要在每一个阶段都让页面有消息能够显示在页面上

那么我们就要在List组件中配置各种不同的选项,分别来判断当前是请求前还是请求中还是请求失败的效果

  data() {
    return {
      info: {
        isFirst: true,
        isLoading: false,
        errMsg: '',
        users: []
      }
    }
  },
  mounted() {
    this.$bus.$on('updataListData', (dataObj) => {
      // 把 this.info 和 dataObj 这两个对象的内容“展开合并”,并生成一个新的对象赋值给 this.info。
      this.info = {...this.info, ...dataObj}
    })
  }

这里将所有数据放入info内就可以让dataObj直接进行赋值info(dataObj是Search组件传来的对象),这样就不用访问this._data 从而直接对这一批数据直接进行赋值

然后分别控制在请求前、请求成功 以及 请求失败时候的不同的控制状态 将该对象传给List组件即可!

      searchUsers() {
        // 请求前更新List数据
        this.$bus.$emit('updataListData', {isFirst:false, isLoading:true, errMsg:'', users:[]})
        axios.get(`https://api.github.com/search/users?q=${this.keyWord}`).then(
          response => {
            // 请求成功后
            this.$bus.$emit('updataListData', { isLoading: false, errMsg: '', users: response.data.items })
          },
          error => {
            // 请求失败后
            this.$bus.$emit('updataListData', { isLoading: false, errMsg:error.message, users: []})
          }
        ) 
      }

 本节素材已上传至Gitee:yihaohhh/我爱Vue - Gitee.com

本章节对我有很大的收获, 希望对你也是!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值