【Vue】Ajax实战-demo3-GitHub用户查询-axios-pubsub

1. 准备工作

界面拆分
在这里插入图片描述

2. 静态页面

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>demo_ajax</title>
    <link rel="stylesheet" href="./static/users_page/bootstrap.css">
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

App.vue

<template>
  <div class="container">
    <search />
    <users-main />
  </div>
</template>

<script>
import Main from "./components/Main.vue";
import Search from "./components/Search.vue";

export default {
     
     
  components: {
     
      Search, UsersMain: Main }, //不能用main作为标签名,就换一个名字
};
</script>

<style>
</style>

Search.vue

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

<script>
export default {
     
     };
</script>

<style>
</style>

Main.vue

<template>
  <div class="row">
    <div class="card">
      <a href="https://github.com/reactjs" target="_blank">
        <img
          src="https://avatars.githubusercontent.com/u/6412038?v=3"
          style="width: 100px"
        />
      </a>
      <p class="card-text">reactjs</p>
    </div>
    <div class="card">
      <a href="https://github.com/reactjs" target="_blank">
        <img
          src="https://avatars.githubusercontent.com/u/6412038?v=3"
          style="width: 100px"
        />
      </a>
      <p class="card-text">reactjs</p>
    </div>
    <div class="card">
      <a href="https://github.com/reactjs" target="_blank">
        <img
          src="https://avatars.githubusercontent.com/u/6412038?v=3"
          style="width: 100px"
        />
      </a>
      <p class="card-text">reactjs</p>
    </div>
    <div class="card">
      <a href="https://github.com/reactjs" target="_blank">
        <img
          src="https://avatars.githubusercontent.com/u/6412038?v=3"
          style="width: 100px"
        />
      </a>
      <p class="card-text">reactjs</p>
    </div>
    <div class="card">
      <a href="https://github.com/reactjs" target="_blank">
        <img
          src="https://avatars.githubusercontent.com/u/6412038?v=3"
          style="width: 100px"
        />
      </a>
      <p class="card-text">reactjs</p>
    </div>
  </div>
</template>

<script>
export default {
     
     };
</script>

<style>
.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>

3. 初始化显示

main.vue

<template>
  <div>
    <h2 v-if="firstView">请输入用户名搜索</h2>
    <h2 v-if="loading">Loading...</h2>
    <h2 v-if="errorMsg">{
   
   {errorMsg}}</h2>
    <div class="row">
      <div class="card" v-for="(user, index) in users" :key="index">
        <a :href="user.url" target="_blank">
          <img
            :src="user.avatar_url"
            style="width: 100px"
          />
        </a>
        <p class="card-text">{
   
   {user.name}}</p>
      </div>
    </div>
  </div>
</template>

<script>
export default {
     
     
  data() {
     
     
    return {
     
     
      // 界面有四个状态
      firstView: true,
      loading: false,
      users: null, //[{url:'', avatar_url: '', name: ''}]
      errorMsg: ''
    };
  },
};
</script>

4. 交互功能实现

输入关键字点击搜索,界面发生变化

Search.vue

<template>
  <section class="jumbotron">
    <h3 class="jumbotron-heading">Search Github Users</h3>
    <div>
      <input
        type="text"
        placeholder="enter the name you search"
        v-model="searchName"
      />
      <button @click="search">Search</button>
    </div>
  </section>
</template>

<script>
import PubSub from "pubsub-js";
export default {
     
     
  data() {
     
     
    return {
     
     
      searchName: "",
    };
  },
  methods: {
     
     
    search() {
     
     
      const searchName = this.searchName.trim();
      if (searchName) {
     
     
        // 发布搜索的消息
        PubSub.publish("search", searchName);
      }
    },
  },
};
</script>

<style>
</style>

Main.vue

<template>
  <div>
    <h2 v-if="firstView">请输入用户名搜索</h2>
    <h2 v-if="loading">Loading...</h2>
    <h2 v-if="errorMsg">{
   
   { errorMsg }}</h2>
    <div class="row" v-else>
      <div class="card" v-for="(user, index) in users" :key="index">
        <a :href="user.url" target="_blank">
          <img :src="user.avatar_url" style="width: 100px" />
        </a>
        <p class="card-text">{
   
   { user.name }}</p>
      </div>
    </div>
  </div>
</template>

<script>
import PubSub from "pubsub-js";
import axios from "axios";
export default {
     
     
  data() {
     
     
    return {
     
     
      // 界面有四个状态
      firstView: true,
      loading: false,
      users: null, //[{url:'', avatar_url: '', name: ''}]
      errorMsg: "",
    };
  },
  mounted() {
     
     
    // 订阅搜索的消息
    PubSub.subscribe("search", (msg, searchName) => {
     
     
      // 说明需要发ajax请求搜索
      const url = `https://api.github.com/search/users?q=${
       
       searchName}`;

      //更新状态(请求中)
      this.firstView = false;
      this.loading = true;
      this.users = null;
      this.errorMsg = "";

      // 发ajax状态
      axios
        .get(url)
        .then((response) => {
     
     
          const result = response.data;
          const users = result.items.map((item) => ({
     
     
            url: item.html_url,
            avatar_url: item.avatar_url,
            name: item.login,
          }));
          // 成功, 更新状态(成功)
          this.loading = false;
          this.users = users;
        })
        .catch((error) => {
     
     
          // 失败, 更新状态(失败)
          this.loading = false;
          this.errorMsg = "请求失败";
        });
    });
  },
};
</script>

5. 效果展示

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44972008/article/details/113992327