《web前端全栈成长计划》Vue第二章学习笔记(下)

举报
张辉 发表于 2020/09/07 17:23:05 2020/09/07
【摘要】 web前端全站成长计划第三阶段vue课程第二章的学习笔记(下)

Vue 第二章 Vue项目与案例

35 Ajax请求vue-ajax

35.1 两个库

  • vue-resource 用于1.x,现在不用。

  • axios库

35.2 下载

npm install vue-resource --save

image.png

npm install axios --save

image.png

35.3 分析需求

当发送请求时,显示loading

收到响应后,显示结果

35.4 vue-resource实现:

main.js

import Vue from 'vue' /* 注意大小写 */
import VueResource from 'vue-resource'
import App from './App'

// 声明使用插件
// 内部会给vm对象和组件对象添加一个属性 $http
Vue.use(VueResource)

App.vue

<template>
  <div>
    <div v-if="!repoUrl">loading</div>
    <div v-else>most star repo is <a :href="repoUrl">{{repoName}}</a></div>
  </div>
</template>

<script>
  // 引入
  export default {
    data (){
      return {
        repoUrl: '',
        repoName: ''
      }
    },

    mounted () {
      // 发ajax请求获取数据
      const url = 'https://api.github.com/search/repositories?q=v&sort=stars'
      this.$http.get(url).then(
        response =>  {
          const result = response.data
          // 得到第一个repo
          const mostRepo = result.items[0]
          this.repoUrl = mostRepo.html_url
          this.repoName = mostRepo.name
        },response => {
          alert('请求失败')
        }
      )
    }
  }
</script>

<style>


</style>

显示效果:

loading:

image.png

结果:

image.png

点击结果链接:

image.png

35.5 axios实现:

axios在调用时做import即可

import axios from 'axios'

调用:

// 使用axios发送ajax请求
axios.get(url).then(
  response =>  {
    const result = response.data
    // 得到第一个repo
    const mostRepo = result.items[0]
    this.repoUrl = mostRepo.html_url
    this.repoName = mostRepo.name
  }).catch(error => {
    alert('请求失败')
})

显示效果:

loading:

image.png

搜索结果:

image.png

点击vue:

image.png

跟前面的结果基本一致。


另一个案例users_page

预期效果:

image.png

36 初始化显示

设计:App, components目录下的Search和Main.

拆分单页面的index,css

拆分完后的效果:

image.png

开始后应为以下页面:

image.png

Main.vue

<template>
  <div>
    <!--
     Search返回有4个状态
    -->
    <h2 v-if="firstView">输入用户名搜索    <h2 v-if="loading">LOADING...    <h2 v-if="errorMsg">{{errorMsg}}    <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 }}      </div>

    </div>
  </div>
</template>

<script>
  export default {
    data () {
      return {
        firstView: true,
        loading: false,
        users: null, // 返回结果
        errorMsg: ''
      }
    }
  }
</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>

显示初始化结果:

image.png

37 搜索

37.1 需求

输入关键字,点击搜索。显示结果.

需要在哪里写ajax请求?因为需要在Main更新状态,所以要在main里面写。

在Search组件中点击,需要通知Main组件去做ajax搜索

兄弟组件:

  1. 使用PubSub实现

  2. 使用props实现(借助于父组件)

37.2 分析:

谁订阅消息?Main

谁发布消息?Search

37.3 实现:

Main

<template>
  <div>
    <!--
     Search返回有4个状态
    -->
    <h2 v-if="firstView">输入用户名搜索    <h2 v-if="loading">LOADING...    <h2 v-if="errorMsg">{{errorMsg}}    <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 }}      </div>

    </div>
  </div>
</template>

<script>
  import PubSub from 'pubsub-js'
  import axios from 'axios'
  export default {
    data () {
      return {
        firstView: true,
        loading: false,
        users: null, // 返回结果
        errorMsg: ''
      }
    },

    mounted () {
      // 订阅消息
      PubSub.subscribe('search', (msg, searchName) => {
        // 需要发ajax
        const url = `https://api.github.com/search/users?q=${searchName}`
        // const url = 'https://api.github.com/search/users?q=aaa'
        console.log('searchName:'+searchName)
        console.log('url:'+url)
        //先更新状态
        this.firstView = false
        this.loading = true
        this.users = null
        this.errorMsg = ''

        axios.get(url).then(
          response =>  {
            const result = response.data
            console.log(result.items)
            const users = result.items.map(item => ({
              url: item.html_url,
              avatar_url: item.avatar_url,
              name: item.login
            }))
            this.loading = false
            this.users = users
            console.log('ajax请求成功')
            // 需要做返回的映射
            // 个数一样,对象不一样
            // 数组使用map

          }).catch(error => {
            console.log('ajax请求失败')
            this.loading = false
            this.errorMsg = '请求失败'

        })
      })
    }
  }
</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>

Search

<template>

    <section class="jumbotron">
      <h3 class="jumbotron-heading">Search Github Users      <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>

实验结果:

github貌似不容易成功,试了好几次:

image.png

终于有一次数据能返回,其他都是返回这样:

image.png

只能等网络好点的时候再将正确的返回截图了。。。


偶尔会成功一次::有些图片还下载不下来。。。

image.png


(全文完,谢谢阅读)


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。